Directory restructuring of object.h
Break object.h into constituent files.
Reduce number of #includes in other GC header files.
Introduce -inl.h files to avoid mirror files #include-ing each other.
Check invariants of verifier RegTypes for all constructors.
Change-Id: Iecf1171c02910ac152d52947330ef456df4043bc
diff --git a/build/Android.common.mk b/build/Android.common.mk
index 1646264..21e829c 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -154,7 +154,6 @@
src/compiled_method.cc \
src/compiler.cc \
src/debugger.cc \
- src/dex_cache.cc \
src/dex_file.cc \
src/dex_file_verifier.cc \
src/dex_instruction.cc \
@@ -193,6 +192,15 @@
src/locks.cc \
src/mem_map.cc \
src/memory_region.cc \
+ src/mirror/abstract_method.cc \
+ src/mirror/array.cc \
+ src/mirror/class.cc \
+ src/mirror/dex_cache.cc \
+ src/mirror/field.cc \
+ src/mirror/object.cc \
+ src/mirror/stack_trace_element.cc \
+ src/mirror/string.cc \
+ src/mirror/throwable.cc \
src/monitor.cc \
src/native/dalvik_system_DexFile.cc \
src/native/dalvik_system_VMDebug.cc \
@@ -229,7 +237,6 @@
src/oat/utils/x86/managed_register_x86.cc \
src/oat_file.cc \
src/oat_writer.cc \
- src/object.cc \
src/offsets.cc \
src/os_linux.cc \
src/primitive.cc \
@@ -242,6 +249,7 @@
src/thread.cc \
src/thread_list.cc \
src/thread_pool.cc \
+ src/timing_logger.cc \
src/trace.cc \
src/utf.cc \
src/utils.cc \
@@ -354,6 +362,7 @@
src/compiler/compiler_enums.h \
src/dex_file.h \
src/dex_instruction.h \
+ src/gc/gc_type.h \
src/gc/space.h \
src/heap.h \
src/indirect_reference_table.h \
@@ -362,8 +371,9 @@
src/jdwp/jdwp.h \
src/jdwp/jdwp_constants.h \
src/locks.h \
- src/object.h \
+ src/mirror/class.h \
src/thread.h \
+ src/thread_state.h \
src/verifier/method_verifier.h
LIBARTTEST_COMMON_SRC_FILES := \
@@ -380,7 +390,6 @@
src/base/unix_file/string_file_test.cc \
src/class_linker_test.cc \
src/compiler_test.cc \
- src/dex_cache_test.cc \
src/dex_file_test.cc \
src/dex_instruction_visitor_test.cc \
src/elf_writer_test.cc \
@@ -395,10 +404,11 @@
src/intern_table_test.cc \
src/jni_compiler_test.cc \
src/jni_internal_test.cc \
+ src/mirror/dex_cache_test.cc \
+ src/mirror/object_test.cc \
src/oat/utils/arm/managed_register_arm_test.cc \
src/oat/utils/x86/managed_register_x86_test.cc \
src/oat_test.cc \
- src/object_test.cc \
src/output_stream_test.cc \
src/reference_table_test.cc \
src/runtime_support_test.cc \
diff --git a/src/barrier_test.cc b/src/barrier_test.cc
index 284be57..bb7bcb3 100644
--- a/src/barrier_test.cc
+++ b/src/barrier_test.cc
@@ -20,6 +20,7 @@
#include "atomic_integer.h"
#include "common_test.h"
+#include "mirror/object_array-inl.h"
#include "thread_pool.h"
#include "UniquePtr.h"
diff --git a/src/base/mutex.cc b/src/base/mutex.cc
index e2ab51f..d09a6a2 100644
--- a/src/base/mutex.cc
+++ b/src/base/mutex.cc
@@ -21,7 +21,6 @@
#include "base/logging.h"
#include "cutils/atomic.h"
-#include "cutils/atomic-inline.h"
#include "runtime.h"
#include "scoped_thread_state_change.h"
#include "thread.h"
diff --git a/src/check_jni.cc b/src/check_jni.cc
index 8f4e921..e53e1c4 100644
--- a/src/check_jni.cc
+++ b/src/check_jni.cc
@@ -21,9 +21,16 @@
#include "base/logging.h"
#include "class_linker.h"
+#include "class_linker-inl.h"
+#include "gc/space.h"
+#include "mirror/class-inl.h"
+#include "mirror/field-inl.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
+#include "mirror/throwable.h"
#include "object_utils.h"
#include "scoped_thread_state_change.h"
-#include "gc/space.h"
#include "thread.h"
#include "runtime.h"
@@ -36,7 +43,7 @@
static void JniAbort(const char* jni_function_name, const char* msg) {
Thread* self = Thread::Current();
ScopedObjectAccess soa(self);
- AbstractMethod* current_method = self->GetCurrentMethod();
+ mirror::AbstractMethod* current_method = self->GetCurrentMethod();
std::ostringstream os;
os << "JNI DETECTED ERROR IN APPLICATION: " << msg;
@@ -123,7 +130,7 @@
NULL
};
-static bool ShouldTrace(JavaVMExt* vm, const AbstractMethod* method)
+static bool ShouldTrace(JavaVMExt* vm, const mirror::AbstractMethod* method)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// If both "-Xcheck:jni" and "-Xjnitrace:" are enabled, we print trace messages
// when a native method that matches the -Xjnitrace argument calls a JNI function
@@ -196,14 +203,14 @@
*/
void CheckFieldType(jobject java_object, jfieldID fid, char prim, bool isStatic)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* f = CheckFieldID(fid);
+ mirror::Field* f = CheckFieldID(fid);
if (f == NULL) {
return;
}
- Class* field_type = FieldHelper(f).GetType();
+ mirror::Class* field_type = FieldHelper(f).GetType();
if (!field_type->IsPrimitive()) {
if (java_object != NULL) {
- Object* obj = soa_.Decode<Object*>(java_object);
+ mirror::Object* obj = soa_.Decode<mirror::Object*>(java_object);
// If java_object is a weak global ref whose referent has been cleared,
// obj will be NULL. Otherwise, obj should always be non-NULL
// and valid.
@@ -243,7 +250,7 @@
*/
void CheckInstanceFieldID(jobject java_object, jfieldID fid)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Object* o = soa_.Decode<Object*>(java_object);
+ mirror::Object* o = soa_.Decode<mirror::Object*>(java_object);
if (o == NULL || !Runtime::Current()->GetHeap()->IsHeapAddress(o)) {
Runtime::Current()->GetHeap()->DumpSpaces();
JniAbortF(function_name_, "field operation on invalid %s: %p",
@@ -251,11 +258,11 @@
return;
}
- Field* f = CheckFieldID(fid);
+ mirror::Field* f = CheckFieldID(fid);
if (f == NULL) {
return;
}
- Class* c = o->GetClass();
+ mirror::Class* c = o->GetClass();
FieldHelper fh(f);
if (c->FindInstanceField(fh.GetName(), fh.GetTypeDescriptor()) == NULL) {
JniAbortF(function_name_, "jfieldID %s not valid for an object of class %s",
@@ -278,7 +285,7 @@
*/
void CheckSig(jmethodID mid, const char* expectedType, bool isStatic)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* m = CheckMethodID(mid);
+ mirror::AbstractMethod* m = CheckMethodID(mid);
if (m == NULL) {
return;
}
@@ -304,8 +311,8 @@
*/
void CheckStaticFieldID(jclass java_class, jfieldID fid)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Class* c = soa_.Decode<Class*>(java_class);
- const Field* f = CheckFieldID(fid);
+ mirror::Class* c = soa_.Decode<mirror::Class*>(java_class);
+ const mirror::Field* f = CheckFieldID(fid);
if (f == NULL) {
return;
}
@@ -326,11 +333,11 @@
*/
void CheckStaticMethod(jclass java_class, jmethodID mid)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const AbstractMethod* m = CheckMethodID(mid);
+ const mirror::AbstractMethod* m = CheckMethodID(mid);
if (m == NULL) {
return;
}
- Class* c = soa_.Decode<Class*>(java_class);
+ mirror::Class* c = soa_.Decode<mirror::Class*>(java_class);
if (!c->IsAssignableFrom(m->GetDeclaringClass())) {
JniAbortF(function_name_, "can't call static %s on class %s",
PrettyMethod(m).c_str(), PrettyClass(c).c_str());
@@ -346,11 +353,11 @@
*/
void CheckVirtualMethod(jobject java_object, jmethodID mid)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const AbstractMethod* m = CheckMethodID(mid);
+ const mirror::AbstractMethod* m = CheckMethodID(mid);
if (m == NULL) {
return;
}
- Object* o = soa_.Decode<Object*>(java_object);
+ mirror::Object* o = soa_.Decode<mirror::Object*>(java_object);
if (!o->InstanceOf(m->GetDeclaringClass())) {
JniAbortF(function_name_, "can't call %s on instance of %s",
PrettyMethod(m).c_str(), PrettyTypeOf(o).c_str());
@@ -397,7 +404,7 @@
SHARED_LOCKS_REQUIRED (Locks::mutator_lock_) {
va_list ap;
- const AbstractMethod* traceMethod = NULL;
+ const mirror::AbstractMethod* traceMethod = NULL;
if ((!soa_.Vm()->trace.empty() || VLOG_IS_ON(third_party_jni)) && has_method_) {
// We need to guard some of the invocation interface's calls: a bad caller might
// use DetachCurrentThread or GetEnv on a thread that's not yet attached.
@@ -455,7 +462,7 @@
msg += (b ? "JNI_TRUE" : "JNI_FALSE");
} else if (ch == 'c') { // jclass
jclass jc = va_arg(ap, jclass);
- Class* c = reinterpret_cast<Class*>(Thread::Current()->DecodeJObject(jc));
+ mirror::Class* c = reinterpret_cast<mirror::Class*>(Thread::Current()->DecodeJObject(jc));
if (c == NULL) {
msg += "NULL";
} else if (c == kInvalidIndirectRefObject || !Runtime::Current()->GetHeap()->IsHeapAddress(c)) {
@@ -470,7 +477,7 @@
}
} else if (ch == 'f') { // jfieldID
jfieldID fid = va_arg(ap, jfieldID);
- Field* f = reinterpret_cast<Field*>(fid);
+ mirror::Field* f = reinterpret_cast<mirror::Field*>(fid);
msg += PrettyField(f);
if (!entry) {
StringAppendF(&msg, " (%p)", fid);
@@ -483,7 +490,7 @@
StringAppendF(&msg, "%d", i);
} else if (ch == 'm') { // jmethodID
jmethodID mid = va_arg(ap, jmethodID);
- AbstractMethod* m = reinterpret_cast<AbstractMethod*>(mid);
+ mirror::AbstractMethod* m = reinterpret_cast<mirror::AbstractMethod*>(mid);
msg += PrettyMethod(m);
if (!entry) {
StringAppendF(&msg, " (%p)", mid);
@@ -623,7 +630,7 @@
return false;
}
- Object* obj = soa_.Decode<Object*>(java_object);
+ mirror::Object* obj = soa_.Decode<mirror::Object*>(java_object);
if (!Runtime::Current()->GetHeap()->IsHeapAddress(obj)) {
Runtime::Current()->GetHeap()->DumpSpaces();
JniAbortF(function_name_, "%s is an invalid %s: %p (%p)",
@@ -677,7 +684,7 @@
return;
}
- Array* a = soa_.Decode<Array*>(java_array);
+ mirror::Array* a = soa_.Decode<mirror::Array*>(java_array);
if (!Runtime::Current()->GetHeap()->IsHeapAddress(a)) {
Runtime::Current()->GetHeap()->DumpSpaces();
JniAbortF(function_name_, "jarray is an invalid %s: %p (%p)",
@@ -693,12 +700,12 @@
}
}
- Field* CheckFieldID(jfieldID fid) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ mirror::Field* CheckFieldID(jfieldID fid) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (fid == NULL) {
JniAbortF(function_name_, "jfieldID was NULL");
return NULL;
}
- Field* f = soa_.DecodeField(fid);
+ mirror::Field* f = soa_.DecodeField(fid);
if (!Runtime::Current()->GetHeap()->IsHeapAddress(f) || !f->IsField()) {
Runtime::Current()->GetHeap()->DumpSpaces();
JniAbortF(function_name_, "invalid jfieldID: %p", fid);
@@ -707,12 +714,12 @@
return f;
}
- AbstractMethod* CheckMethodID(jmethodID mid) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ mirror::AbstractMethod* CheckMethodID(jmethodID mid) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (mid == NULL) {
JniAbortF(function_name_, "jmethodID was NULL");
return NULL;
}
- AbstractMethod* m = soa_.DecodeMethod(mid);
+ mirror::AbstractMethod* m = soa_.DecodeMethod(mid);
if (!Runtime::Current()->GetHeap()->IsHeapAddress(m) || !m->IsMethod()) {
Runtime::Current()->GetHeap()->DumpSpaces();
JniAbortF(function_name_, "invalid jmethodID: %p", mid);
@@ -733,7 +740,7 @@
return;
}
- Object* o = soa_.Decode<Object*>(java_object);
+ mirror::Object* o = soa_.Decode<mirror::Object*>(java_object);
if (!Runtime::Current()->GetHeap()->IsHeapAddress(o)) {
Runtime::Current()->GetHeap()->DumpSpaces();
// TODO: when we remove work_around_app_jni_bugs, this should be impossible.
@@ -1084,7 +1091,7 @@
static void* CreateGuardedPACopy(JNIEnv* env, const jarray java_array, jboolean* isCopy) {
ScopedObjectAccess soa(env);
- Array* a = soa.Decode<Array*>(java_array);
+ mirror::Array* a = soa.Decode<mirror::Array*>(java_array);
size_t component_size = a->GetClass()->GetComponentSize();
size_t byte_count = a->GetLength() * component_size;
void* result = GuardedCopy::Create(a->GetRawData(component_size), byte_count, true);
@@ -1104,7 +1111,7 @@
}
ScopedObjectAccess soa(env);
- Array* a = soa.Decode<Array*>(java_array);
+ mirror::Array* a = soa.Decode<mirror::Array*>(java_array);
GuardedCopy::Check(__FUNCTION__, dataBuf, true);
@@ -1467,7 +1474,7 @@
#define NON_VOID_RETURN(_retsig, _ctype) return CHECK_JNI_EXIT(_retsig, (_ctype) result)
#define VOID_RETURN CHECK_JNI_EXIT_VOID()
-CALL(jobject, Object, Object* result, result = reinterpret_cast<Object*>, NON_VOID_RETURN("L", jobject), "L");
+CALL(jobject, Object, mirror::Object* result, result = reinterpret_cast<mirror::Object*>, NON_VOID_RETURN("L", jobject), "L");
CALL(jboolean, Boolean, jboolean result, result =, NON_VOID_RETURN("Z", jboolean), "Z");
CALL(jbyte, Byte, jbyte result, result =, NON_VOID_RETURN("B", jbyte), "B");
CALL(jchar, Char, jchar result, result =, NON_VOID_RETURN("C", jchar), "C");
@@ -1492,7 +1499,7 @@
CHECK_JNI_ENTRY(kFlag_CritOkay, "Esp", env, java_string, isCopy);
const jchar* result = baseEnv(env)->GetStringChars(env, java_string, isCopy);
if (sc.ForceCopy() && result != NULL) {
- String* s = sc.soa().Decode<String*>(java_string);
+ mirror::String* s = sc.soa().Decode<mirror::String*>(java_string);
int byteCount = s->GetLength() * 2;
result = (const jchar*) GuardedCopy::Create(result, byteCount, false);
if (isCopy != NULL) {
@@ -1719,7 +1726,7 @@
CHECK_JNI_ENTRY(kFlag_CritGet, "Esp", env, java_string, isCopy);
const jchar* result = baseEnv(env)->GetStringCritical(env, java_string, isCopy);
if (sc.ForceCopy() && result != NULL) {
- String* s = sc.soa().Decode<String*>(java_string);
+ mirror::String* s = sc.soa().Decode<mirror::String*>(java_string);
int byteCount = s->GetLength() * 2;
result = (const jchar*) GuardedCopy::Create(result, byteCount, false);
if (isCopy != NULL) {
diff --git a/src/class_linker-inl.h b/src/class_linker-inl.h
new file mode 100644
index 0000000..6cf4991
--- /dev/null
+++ b/src/class_linker-inl.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_CLASS_LINKER_INL_H_
+#define ART_SRC_CLASS_LINKER_INL_H_
+
+#include "class_linker.h"
+
+#include "mirror/dex_cache.h"
+#include "mirror/field.h"
+#include "mirror/iftable.h"
+#include "mirror/object_array.h"
+
+namespace art {
+
+inline mirror::String* ClassLinker::ResolveString(uint32_t string_idx,
+ const mirror::AbstractMethod* referrer) {
+ mirror::String* resolved_string = referrer->GetDexCacheStrings()->Get(string_idx);
+ if (UNLIKELY(resolved_string == NULL)) {
+ mirror::Class* declaring_class = referrer->GetDeclaringClass();
+ mirror::DexCache* dex_cache = declaring_class->GetDexCache();
+ const DexFile& dex_file = *dex_cache->GetDexFile();
+ resolved_string = ResolveString(dex_file, string_idx, dex_cache);
+ }
+ return resolved_string;
+}
+
+inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx,
+ const mirror::AbstractMethod* referrer) {
+ mirror::Class* resolved_type = referrer->GetDexCacheResolvedTypes()->Get(type_idx);
+ if (UNLIKELY(resolved_type == NULL)) {
+ mirror::Class* declaring_class = referrer->GetDeclaringClass();
+ mirror::DexCache* dex_cache = declaring_class->GetDexCache();
+ mirror::ClassLoader* class_loader = declaring_class->GetClassLoader();
+ const DexFile& dex_file = *dex_cache->GetDexFile();
+ resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader);
+ }
+ return resolved_type;
+}
+
+inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, const mirror::Field* referrer) {
+ mirror::Class* declaring_class = referrer->GetDeclaringClass();
+ mirror::DexCache* dex_cache = declaring_class->GetDexCache();
+ mirror::Class* resolved_type = dex_cache->GetResolvedType(type_idx);
+ if (UNLIKELY(resolved_type == NULL)) {
+ mirror::ClassLoader* class_loader = declaring_class->GetClassLoader();
+ const DexFile& dex_file = *dex_cache->GetDexFile();
+ resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader);
+ }
+ return resolved_type;
+}
+
+inline mirror::AbstractMethod* ClassLinker::ResolveMethod(uint32_t method_idx,
+ const mirror::AbstractMethod* referrer,
+ InvokeType type) {
+ mirror::AbstractMethod* resolved_method =
+ referrer->GetDexCacheResolvedMethods()->Get(method_idx);
+ if (UNLIKELY(resolved_method == NULL || resolved_method->IsRuntimeMethod())) {
+ mirror::Class* declaring_class = referrer->GetDeclaringClass();
+ mirror::DexCache* dex_cache = declaring_class->GetDexCache();
+ mirror::ClassLoader* class_loader = declaring_class->GetClassLoader();
+ const DexFile& dex_file = *dex_cache->GetDexFile();
+ resolved_method = ResolveMethod(dex_file, method_idx, dex_cache, class_loader, referrer, type);
+ }
+ return resolved_method;
+}
+
+inline mirror::Field* ClassLinker::ResolveField(uint32_t field_idx,
+ const mirror::AbstractMethod* referrer,
+ bool is_static) {
+ mirror::Field* resolved_field =
+ referrer->GetDeclaringClass()->GetDexCache()->GetResolvedField(field_idx);
+ if (UNLIKELY(resolved_field == NULL)) {
+ mirror::Class* declaring_class = referrer->GetDeclaringClass();
+ mirror::DexCache* dex_cache = declaring_class->GetDexCache();
+ mirror::ClassLoader* class_loader = declaring_class->GetClassLoader();
+ const DexFile& dex_file = *dex_cache->GetDexFile();
+ resolved_field = ResolveField(dex_file, field_idx, dex_cache, class_loader, is_static);
+ }
+ return resolved_field;
+}
+
+template <class T>
+inline mirror::ObjectArray<T>* ClassLinker::AllocObjectArray(Thread* self, size_t length) {
+ return mirror::ObjectArray<T>::Alloc(self, GetClassRoot(kObjectArrayClass), length);
+}
+
+inline mirror::ObjectArray<mirror::Class>* ClassLinker::AllocClassArray(Thread* self,
+ size_t length) {
+ return mirror::ObjectArray<mirror::Class>::Alloc(self, GetClassRoot(kClassArrayClass), length);
+}
+
+inline mirror::ObjectArray<mirror::String>* ClassLinker::AllocStringArray(Thread* self,
+ size_t length) {
+ return mirror::ObjectArray<mirror::String>::Alloc(self, GetClassRoot(kJavaLangStringArrayClass),
+ length);
+}
+
+inline mirror::ObjectArray<mirror::AbstractMethod>* ClassLinker::AllocAbstractMethodArray(Thread* self,
+ size_t length) {
+ return mirror::ObjectArray<mirror::AbstractMethod>::Alloc(self,
+ GetClassRoot(kJavaLangReflectAbstractMethodArrayClass), length);
+}
+
+inline mirror::ObjectArray<mirror::AbstractMethod>* ClassLinker::AllocMethodArray(Thread* self,
+ size_t length) {
+ return mirror::ObjectArray<mirror::AbstractMethod>::Alloc(self,
+ GetClassRoot(kJavaLangReflectMethodArrayClass), length);
+}
+
+inline mirror::IfTable* ClassLinker::AllocIfTable(Thread* self, size_t ifcount) {
+ return down_cast<mirror::IfTable*>(
+ mirror::IfTable::Alloc(self, GetClassRoot(kObjectArrayClass), ifcount * mirror::IfTable::kMax));
+}
+
+inline mirror::ObjectArray<mirror::Field>* ClassLinker::AllocFieldArray(Thread* self,
+ size_t length) {
+ return mirror::ObjectArray<mirror::Field>::Alloc(self,
+ GetClassRoot(kJavaLangReflectFieldArrayClass),
+ length);
+}
+
+inline mirror::Class* ClassLinker::GetClassRoot(ClassRoot class_root)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(class_roots_ != NULL);
+ mirror::Class* klass = class_roots_->Get(class_root);
+ DCHECK(klass != NULL);
+ return klass;
+}
+
+} // namespace art
+
+#endif // ART_SRC_CLASS_LINKER_INL_H_
diff --git a/src/class_linker.cc b/src/class_linker.cc
index c43c397..9aa4dda 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -31,17 +31,28 @@
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/unix_file/fd_file.h"
-#include "class_loader.h"
+#include "class_linker-inl.h"
#include "debugger.h"
-#include "dex_cache.h"
#include "dex_file.h"
+#include "gc/card_table-inl.h"
#include "heap.h"
#include "intern_table.h"
#include "interpreter/interpreter.h"
#include "leb128.h"
#include "oat.h"
#include "oat_file.h"
-#include "object.h"
+#include "mirror/class.h"
+#include "mirror/class-inl.h"
+#include "mirror/class_loader.h"
+#include "mirror/dex_cache.h"
+#include "mirror/field-inl.h"
+#include "mirror/iftable-inl.h"
+#include "mirror/abstract_method.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
+#include "mirror/proxy.h"
+#include "mirror/stack_trace_element.h"
#include "object_utils.h"
#include "os.h"
#include "runtime.h"
@@ -58,6 +69,7 @@
#include "thread.h"
#include "UniquePtr.h"
#include "utils.h"
+#include "verifier/method_verifier.h"
#include "well_known_classes.h"
namespace art {
@@ -92,7 +104,7 @@
va_end(args);
}
-static void ThrowNoSuchFieldError(const StringPiece& scope, Class* c, const StringPiece& type,
+static void ThrowNoSuchFieldError(const StringPiece& scope, mirror::Class* c, const StringPiece& type,
const StringPiece& name)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ClassHelper kh(c);
@@ -116,7 +128,7 @@
va_end(args);
}
-static void ThrowEarlierClassFailure(Class* c)
+static void ThrowEarlierClassFailure(mirror::Class* c)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// The class failed to initialize on a previous attempt, so we want to throw
// a NoClassDefFoundError (v2 2.17.5). The exception to this rule is if we
@@ -239,45 +251,47 @@
// 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(self, NULL, sizeof(ClassClass))));
+ SirtRef<mirror::Class>
+ java_lang_Class(self,
+ down_cast<mirror::Class*>(heap->AllocObject(self, NULL,
+ sizeof(mirror::ClassClass))));
CHECK(java_lang_Class.get() != NULL);
- Class::SetClassClass(java_lang_Class.get());
+ mirror::Class::SetClassClass(java_lang_Class.get());
java_lang_Class->SetClass(java_lang_Class.get());
- java_lang_Class->SetClassSize(sizeof(ClassClass));
- // AllocClass(Class*) can now be used
+ java_lang_Class->SetClassSize(sizeof(mirror::ClassClass));
+ // AllocClass(mirror::Class*) can now be used
// Class[] is used for reflection support.
- SirtRef<Class> class_array_class(self, AllocClass(self, java_lang_Class.get(), sizeof(Class)));
+ SirtRef<mirror::Class> class_array_class(self, AllocClass(self, java_lang_Class.get(), sizeof(mirror::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(self, java_lang_Class.get(), sizeof(Class)));
+ SirtRef<mirror::Class> java_lang_Object(self, AllocClass(self, java_lang_Class.get(), sizeof(mirror::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);
+ java_lang_Object->SetStatus(mirror::Class::kStatusLoaded);
// Object[] next to hold class roots.
- SirtRef<Class> object_array_class(self, AllocClass(self, java_lang_Class.get(), sizeof(Class)));
+ SirtRef<mirror::Class> object_array_class(self, AllocClass(self, java_lang_Class.get(), sizeof(mirror::Class)));
object_array_class->SetComponentType(java_lang_Object.get());
// Setup the char class to be used for char[].
- SirtRef<Class> char_class(self, AllocClass(self, java_lang_Class.get(), sizeof(Class)));
+ SirtRef<mirror::Class> char_class(self, AllocClass(self, java_lang_Class.get(), sizeof(mirror::Class)));
// Setup the char[] class to be used for String.
- SirtRef<Class> char_array_class(self, AllocClass(self, java_lang_Class.get(), sizeof(Class)));
+ SirtRef<mirror::Class> char_array_class(self, AllocClass(self, java_lang_Class.get(), sizeof(mirror::Class)));
char_array_class->SetComponentType(char_class.get());
- CharArray::SetArrayClass(char_array_class.get());
+ mirror::CharArray::SetArrayClass(char_array_class.get());
// Setup String.
- 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);
+ SirtRef<mirror::Class> java_lang_String(self, AllocClass(self, java_lang_Class.get(), sizeof(mirror::StringClass)));
+ mirror::String::SetClass(java_lang_String.get());
+ java_lang_String->SetObjectSize(sizeof(mirror::String));
+ java_lang_String->SetStatus(mirror::Class::kStatusResolved);
// Create storage for root classes, save away our work so far (requires descriptors).
- class_roots_ = ObjectArray<Class>::Alloc(self, object_array_class.get(), kClassRootsMax);
+ class_roots_ = mirror::ObjectArray<mirror::Class>::Alloc(self, object_array_class.get(), kClassRootsMax);
CHECK(class_roots_ != NULL);
SetClassRoot(kJavaLangClass, java_lang_Class.get());
SetClassRoot(kJavaLangObject, java_lang_Object.get());
@@ -300,68 +314,69 @@
array_iftable_ = AllocIfTable(self, 2);
// Create int array type for AllocDexCache (done in AppendToBootClassPath).
- SirtRef<Class> int_array_class(self, AllocClass(self, java_lang_Class.get(), sizeof(Class)));
+ SirtRef<mirror::Class> int_array_class(self, AllocClass(self, java_lang_Class.get(), sizeof(mirror::Class)));
int_array_class->SetComponentType(GetClassRoot(kPrimitiveInt));
- IntArray::SetArrayClass(int_array_class.get());
+ mirror::IntArray::SetArrayClass(int_array_class.get());
SetClassRoot(kIntArrayClass, int_array_class.get());
// now that these are registered, we can use AllocClass() and AllocObjectArray
// Set up DexCache. This cannot be done later since AppendToBootClassPath calls AllocDexCache.
- SirtRef<Class>
- java_lang_DexCache(self, AllocClass(self, java_lang_Class.get(), sizeof(DexCacheClass)));
+ SirtRef<mirror::Class>
+ java_lang_DexCache(self, AllocClass(self, java_lang_Class.get(), sizeof(mirror::DexCacheClass)));
SetClassRoot(kJavaLangDexCache, java_lang_DexCache.get());
- java_lang_DexCache->SetObjectSize(sizeof(DexCacheClass));
- java_lang_DexCache->SetStatus(Class::kStatusResolved);
+ java_lang_DexCache->SetObjectSize(sizeof(mirror::DexCacheClass));
+ java_lang_DexCache->SetStatus(mirror::Class::kStatusResolved);
// Constructor, Field, Method, and AbstractMethod are necessary so that FindClass can link members.
- SirtRef<Class> java_lang_reflect_Field(self, AllocClass(self, java_lang_Class.get(),
- sizeof(FieldClass)));
+ SirtRef<mirror::Class> java_lang_reflect_Field(self, AllocClass(self, java_lang_Class.get(),
+ sizeof(mirror::FieldClass)));
CHECK(java_lang_reflect_Field.get() != NULL);
- java_lang_reflect_Field->SetObjectSize(sizeof(Field));
+ java_lang_reflect_Field->SetObjectSize(sizeof(mirror::Field));
SetClassRoot(kJavaLangReflectField, java_lang_reflect_Field.get());
- java_lang_reflect_Field->SetStatus(Class::kStatusResolved);
- Field::SetClass(java_lang_reflect_Field.get());
+ java_lang_reflect_Field->SetStatus(mirror::Class::kStatusResolved);
+ mirror::Field::SetClass(java_lang_reflect_Field.get());
- SirtRef<Class> java_lang_reflect_AbstractMethod(self, AllocClass(self, java_lang_Class.get(),
- sizeof(MethodClass)));
+ SirtRef<mirror::Class> java_lang_reflect_AbstractMethod(self, AllocClass(self, java_lang_Class.get(),
+ sizeof(mirror::AbstractMethodClass)));
CHECK(java_lang_reflect_AbstractMethod.get() != NULL);
- java_lang_reflect_AbstractMethod->SetObjectSize(sizeof(AbstractMethod));
+ java_lang_reflect_AbstractMethod->SetObjectSize(sizeof(mirror::AbstractMethod));
SetClassRoot(kJavaLangReflectAbstractMethod, java_lang_reflect_AbstractMethod.get());
- java_lang_reflect_AbstractMethod->SetStatus(Class::kStatusResolved);
+ java_lang_reflect_AbstractMethod->SetStatus(mirror::Class::kStatusResolved);
- SirtRef<Class> java_lang_reflect_Constructor(self, AllocClass(self, java_lang_Class.get(),
- sizeof(MethodClass)));
+ SirtRef<mirror::Class> java_lang_reflect_Constructor(self, AllocClass(self, java_lang_Class.get(),
+ sizeof(mirror::AbstractMethodClass)));
CHECK(java_lang_reflect_Constructor.get() != NULL);
- java_lang_reflect_Constructor->SetObjectSize(sizeof(Constructor));
+ java_lang_reflect_Constructor->SetObjectSize(sizeof(mirror::Constructor));
java_lang_reflect_Constructor->SetSuperClass(java_lang_reflect_AbstractMethod.get());
SetClassRoot(kJavaLangReflectConstructor, java_lang_reflect_Constructor.get());
- java_lang_reflect_Constructor->SetStatus(Class::kStatusResolved);
+ java_lang_reflect_Constructor->SetStatus(mirror::Class::kStatusResolved);
- SirtRef<Class> java_lang_reflect_Method(self, AllocClass(self, java_lang_Class.get(),
- sizeof(MethodClass)));
+ SirtRef<mirror::Class> java_lang_reflect_Method(self, AllocClass(self, java_lang_Class.get(),
+ sizeof(mirror::AbstractMethodClass)));
CHECK(java_lang_reflect_Method.get() != NULL);
- java_lang_reflect_Method->SetObjectSize(sizeof(Method));
+ java_lang_reflect_Method->SetObjectSize(sizeof(mirror::Method));
java_lang_reflect_Method->SetSuperClass(java_lang_reflect_AbstractMethod.get());
SetClassRoot(kJavaLangReflectMethod, java_lang_reflect_Method.get());
- java_lang_reflect_Method->SetStatus(Class::kStatusResolved);
+ java_lang_reflect_Method->SetStatus(mirror::Class::kStatusResolved);
- AbstractMethod::SetClasses(java_lang_reflect_Constructor.get(), java_lang_reflect_Method.get());
+ mirror::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(self, java_lang_Class.get(), sizeof(Class)));
+ SirtRef<mirror::Class> object_array_string(self, AllocClass(self, java_lang_Class.get(), sizeof(mirror::Class)));
object_array_string->SetComponentType(java_lang_String.get());
SetClassRoot(kJavaLangStringArrayClass, object_array_string.get());
- SirtRef<Class> object_array_abstract_method(self, AllocClass(self, java_lang_Class.get(), sizeof(Class)));
+ SirtRef<mirror::Class> object_array_abstract_method(self, AllocClass(self, java_lang_Class.get(), sizeof(mirror::Class)));
object_array_abstract_method->SetComponentType(java_lang_reflect_AbstractMethod.get());
SetClassRoot(kJavaLangReflectAbstractMethodArrayClass, object_array_abstract_method.get());
- SirtRef<Class> object_array_field(self, AllocClass(self, java_lang_Class.get(), sizeof(Class)));
+ SirtRef<mirror::Class> object_array_field(self, AllocClass(self, java_lang_Class.get(), sizeof(mirror::Class)));
object_array_field->SetComponentType(java_lang_reflect_Field.get());
SetClassRoot(kJavaLangReflectFieldArrayClass, object_array_field.get());
- SirtRef<Class> object_array_method(self, AllocClass(self, java_lang_Class.get(), sizeof(Class)));
+ SirtRef<mirror::Class> object_array_method(self, AllocClass(self, java_lang_Class.get(), sizeof(mirror::Class)));
object_array_method->SetComponentType(java_lang_reflect_Method.get());
SetClassRoot(kJavaLangReflectMethodArrayClass, object_array_method.get());
@@ -382,55 +397,55 @@
SetClassRoot(kPrimitiveChar, char_class.get()); // needs descriptor
// Object, String and DexCache need to be rerun through FindSystemClass to finish init
- java_lang_Object->SetStatus(Class::kStatusNotReady);
- Class* Object_class = FindSystemClass("Ljava/lang/Object;");
+ java_lang_Object->SetStatus(mirror::Class::kStatusNotReady);
+ mirror::Class* Object_class = FindSystemClass("Ljava/lang/Object;");
CHECK_EQ(java_lang_Object.get(), Object_class);
- CHECK_EQ(java_lang_Object->GetObjectSize(), sizeof(Object));
- java_lang_String->SetStatus(Class::kStatusNotReady);
- Class* String_class = FindSystemClass("Ljava/lang/String;");
+ CHECK_EQ(java_lang_Object->GetObjectSize(), sizeof(mirror::Object));
+ java_lang_String->SetStatus(mirror::Class::kStatusNotReady);
+ mirror::Class* String_class = FindSystemClass("Ljava/lang/String;");
CHECK_EQ(java_lang_String.get(), String_class);
- CHECK_EQ(java_lang_String->GetObjectSize(), sizeof(String));
- java_lang_DexCache->SetStatus(Class::kStatusNotReady);
- Class* DexCache_class = FindSystemClass("Ljava/lang/DexCache;");
+ CHECK_EQ(java_lang_String->GetObjectSize(), sizeof(mirror::String));
+ java_lang_DexCache->SetStatus(mirror::Class::kStatusNotReady);
+ mirror::Class* DexCache_class = FindSystemClass("Ljava/lang/DexCache;");
CHECK_EQ(java_lang_String.get(), String_class);
CHECK_EQ(java_lang_DexCache.get(), DexCache_class);
- CHECK_EQ(java_lang_DexCache->GetObjectSize(), sizeof(DexCache));
+ CHECK_EQ(java_lang_DexCache->GetObjectSize(), sizeof(mirror::DexCache));
// Setup the primitive array type classes - can't be done until Object has a vtable.
SetClassRoot(kBooleanArrayClass, FindSystemClass("[Z"));
- BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
+ mirror::BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
SetClassRoot(kByteArrayClass, FindSystemClass("[B"));
- ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
+ mirror::ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
- Class* found_char_array_class = FindSystemClass("[C");
+ mirror::Class* found_char_array_class = FindSystemClass("[C");
CHECK_EQ(char_array_class.get(), found_char_array_class);
SetClassRoot(kShortArrayClass, FindSystemClass("[S"));
- ShortArray::SetArrayClass(GetClassRoot(kShortArrayClass));
+ mirror::ShortArray::SetArrayClass(GetClassRoot(kShortArrayClass));
- Class* found_int_array_class = FindSystemClass("[I");
+ mirror::Class* found_int_array_class = FindSystemClass("[I");
CHECK_EQ(int_array_class.get(), found_int_array_class);
SetClassRoot(kLongArrayClass, FindSystemClass("[J"));
- LongArray::SetArrayClass(GetClassRoot(kLongArrayClass));
+ mirror::LongArray::SetArrayClass(GetClassRoot(kLongArrayClass));
SetClassRoot(kFloatArrayClass, FindSystemClass("[F"));
- FloatArray::SetArrayClass(GetClassRoot(kFloatArrayClass));
+ mirror::FloatArray::SetArrayClass(GetClassRoot(kFloatArrayClass));
SetClassRoot(kDoubleArrayClass, FindSystemClass("[D"));
- DoubleArray::SetArrayClass(GetClassRoot(kDoubleArrayClass));
+ mirror::DoubleArray::SetArrayClass(GetClassRoot(kDoubleArrayClass));
- Class* found_class_array_class = FindSystemClass("[Ljava/lang/Class;");
+ mirror::Class* found_class_array_class = FindSystemClass("[Ljava/lang/Class;");
CHECK_EQ(class_array_class.get(), found_class_array_class);
- Class* found_object_array_class = FindSystemClass("[Ljava/lang/Object;");
+ mirror::Class* found_object_array_class = FindSystemClass("[Ljava/lang/Object;");
CHECK_EQ(object_array_class.get(), found_object_array_class);
// Setup the single, global copy of "iftable".
- Class* java_lang_Cloneable = FindSystemClass("Ljava/lang/Cloneable;");
+ mirror::Class* java_lang_Cloneable = FindSystemClass("Ljava/lang/Cloneable;");
CHECK(java_lang_Cloneable != NULL);
- Class* java_io_Serializable = FindSystemClass("Ljava/io/Serializable;");
+ mirror::Class* java_io_Serializable = FindSystemClass("Ljava/io/Serializable;");
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.
@@ -446,79 +461,79 @@
CHECK_EQ(java_io_Serializable, kh.GetDirectInterface(1));
// Run Class, Constructor, Field, and Method through FindSystemClass. This initializes their
// dex_cache_ fields and register them in classes_.
- Class* Class_class = FindSystemClass("Ljava/lang/Class;");
+ mirror::Class* Class_class = FindSystemClass("Ljava/lang/Class;");
CHECK_EQ(java_lang_Class.get(), Class_class);
- java_lang_reflect_AbstractMethod->SetStatus(Class::kStatusNotReady);
- Class* Abstract_method_class = FindSystemClass("Ljava/lang/reflect/AbstractMethod;");
+ java_lang_reflect_AbstractMethod->SetStatus(mirror::Class::kStatusNotReady);
+ mirror::Class* Abstract_method_class = FindSystemClass("Ljava/lang/reflect/AbstractMethod;");
CHECK_EQ(java_lang_reflect_AbstractMethod.get(), Abstract_method_class);
// Method extends AbstractMethod so must reset after.
- java_lang_reflect_Method->SetStatus(Class::kStatusNotReady);
- Class* Method_class = FindSystemClass("Ljava/lang/reflect/Method;");
+ java_lang_reflect_Method->SetStatus(mirror::Class::kStatusNotReady);
+ mirror::Class* Method_class = FindSystemClass("Ljava/lang/reflect/Method;");
CHECK_EQ(java_lang_reflect_Method.get(), Method_class);
// Constructor extends AbstractMethod so must reset after.
- java_lang_reflect_Constructor->SetStatus(Class::kStatusNotReady);
- Class* Constructor_class = FindSystemClass("Ljava/lang/reflect/Constructor;");
+ java_lang_reflect_Constructor->SetStatus(mirror::Class::kStatusNotReady);
+ mirror::Class* Constructor_class = FindSystemClass("Ljava/lang/reflect/Constructor;");
CHECK_EQ(java_lang_reflect_Constructor.get(), Constructor_class);
- java_lang_reflect_Field->SetStatus(Class::kStatusNotReady);
- Class* Field_class = FindSystemClass("Ljava/lang/reflect/Field;");
+ java_lang_reflect_Field->SetStatus(mirror::Class::kStatusNotReady);
+ mirror::Class* Field_class = FindSystemClass("Ljava/lang/reflect/Field;");
CHECK_EQ(java_lang_reflect_Field.get(), Field_class);
- Class* String_array_class = FindSystemClass(class_roots_descriptors_[kJavaLangStringArrayClass]);
+ mirror::Class* String_array_class = FindSystemClass(class_roots_descriptors_[kJavaLangStringArrayClass]);
CHECK_EQ(object_array_string.get(), String_array_class);
- Class* Abstract_method_array_class =
+ mirror::Class* Abstract_method_array_class =
FindSystemClass(class_roots_descriptors_[kJavaLangReflectAbstractMethodArrayClass]);
CHECK_EQ(object_array_abstract_method.get(), Abstract_method_array_class);
- Class* Field_array_class = FindSystemClass(class_roots_descriptors_[kJavaLangReflectFieldArrayClass]);
+ mirror::Class* Field_array_class = FindSystemClass(class_roots_descriptors_[kJavaLangReflectFieldArrayClass]);
CHECK_EQ(object_array_field.get(), Field_array_class);
- Class* Method_array_class =
+ mirror::Class* Method_array_class =
FindSystemClass(class_roots_descriptors_[kJavaLangReflectMethodArrayClass]);
CHECK_EQ(object_array_method.get(), Method_array_class);
// End of special init trickery, subsequent classes may be loaded via FindSystemClass.
// Create java.lang.reflect.Proxy root.
- Class* java_lang_reflect_Proxy = FindSystemClass("Ljava/lang/reflect/Proxy;");
+ mirror::Class* java_lang_reflect_Proxy = FindSystemClass("Ljava/lang/reflect/Proxy;");
SetClassRoot(kJavaLangReflectProxy, java_lang_reflect_Proxy);
// java.lang.ref classes need to be specially flagged, but otherwise are normal classes
- Class* java_lang_ref_Reference = FindSystemClass("Ljava/lang/ref/Reference;");
+ mirror::Class* java_lang_ref_Reference = FindSystemClass("Ljava/lang/ref/Reference;");
SetClassRoot(kJavaLangRefReference, java_lang_ref_Reference);
- Class* java_lang_ref_FinalizerReference = FindSystemClass("Ljava/lang/ref/FinalizerReference;");
+ mirror::Class* java_lang_ref_FinalizerReference = FindSystemClass("Ljava/lang/ref/FinalizerReference;");
java_lang_ref_FinalizerReference->SetAccessFlags(
java_lang_ref_FinalizerReference->GetAccessFlags() |
kAccClassIsReference | kAccClassIsFinalizerReference);
- Class* java_lang_ref_PhantomReference = FindSystemClass("Ljava/lang/ref/PhantomReference;");
+ mirror::Class* java_lang_ref_PhantomReference = FindSystemClass("Ljava/lang/ref/PhantomReference;");
java_lang_ref_PhantomReference->SetAccessFlags(
java_lang_ref_PhantomReference->GetAccessFlags() |
kAccClassIsReference | kAccClassIsPhantomReference);
- Class* java_lang_ref_SoftReference = FindSystemClass("Ljava/lang/ref/SoftReference;");
+ mirror::Class* java_lang_ref_SoftReference = FindSystemClass("Ljava/lang/ref/SoftReference;");
java_lang_ref_SoftReference->SetAccessFlags(
java_lang_ref_SoftReference->GetAccessFlags() | kAccClassIsReference);
- Class* java_lang_ref_WeakReference = FindSystemClass("Ljava/lang/ref/WeakReference;");
+ mirror::Class* java_lang_ref_WeakReference = FindSystemClass("Ljava/lang/ref/WeakReference;");
java_lang_ref_WeakReference->SetAccessFlags(
java_lang_ref_WeakReference->GetAccessFlags() |
kAccClassIsReference | kAccClassIsWeakReference);
// Setup the ClassLoader, verifying the object_size_.
- Class* java_lang_ClassLoader = FindSystemClass("Ljava/lang/ClassLoader;");
- CHECK_EQ(java_lang_ClassLoader->GetObjectSize(), sizeof(ClassLoader));
+ mirror::Class* java_lang_ClassLoader = FindSystemClass("Ljava/lang/ClassLoader;");
+ CHECK_EQ(java_lang_ClassLoader->GetObjectSize(), sizeof(mirror::ClassLoader));
SetClassRoot(kJavaLangClassLoader, java_lang_ClassLoader);
// Set up java.lang.Throwable, java.lang.ClassNotFoundException, and
// java.lang.StackTraceElement as a convenience.
SetClassRoot(kJavaLangThrowable, FindSystemClass("Ljava/lang/Throwable;"));
- Throwable::SetClass(GetClassRoot(kJavaLangThrowable));
+ mirror::Throwable::SetClass(GetClassRoot(kJavaLangThrowable));
SetClassRoot(kJavaLangClassNotFoundException, FindSystemClass("Ljava/lang/ClassNotFoundException;"));
SetClassRoot(kJavaLangStackTraceElement, FindSystemClass("Ljava/lang/StackTraceElement;"));
SetClassRoot(kJavaLangStackTraceElementArrayClass, FindSystemClass("[Ljava/lang/StackTraceElement;"));
- StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
+ mirror::StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
FinishInit();
@@ -532,37 +547,37 @@
// Note: we hard code the field indexes here rather than using FindInstanceField
// as the types of the field can't be resolved prior to the runtime being
// fully initialized
- Class* java_lang_ref_Reference = GetClassRoot(kJavaLangRefReference);
- Class* java_lang_ref_ReferenceQueue = FindSystemClass("Ljava/lang/ref/ReferenceQueue;");
- Class* java_lang_ref_FinalizerReference = FindSystemClass("Ljava/lang/ref/FinalizerReference;");
+ mirror::Class* java_lang_ref_Reference = GetClassRoot(kJavaLangRefReference);
+ mirror::Class* java_lang_ref_ReferenceQueue = FindSystemClass("Ljava/lang/ref/ReferenceQueue;");
+ mirror::Class* java_lang_ref_FinalizerReference = FindSystemClass("Ljava/lang/ref/FinalizerReference;");
const DexFile& java_lang_dex = *java_lang_ref_Reference->GetDexCache()->GetDexFile();
- Field* pendingNext = java_lang_ref_Reference->GetInstanceField(0);
+ mirror::Field* pendingNext = java_lang_ref_Reference->GetInstanceField(0);
FieldHelper fh(pendingNext, this);
CHECK_STREQ(fh.GetName(), "pendingNext");
CHECK_EQ(java_lang_dex.GetFieldId(pendingNext->GetDexFieldIndex()).type_idx_,
java_lang_ref_Reference->GetDexTypeIndex());
- Field* queue = java_lang_ref_Reference->GetInstanceField(1);
+ mirror::Field* queue = java_lang_ref_Reference->GetInstanceField(1);
fh.ChangeField(queue);
CHECK_STREQ(fh.GetName(), "queue");
CHECK_EQ(java_lang_dex.GetFieldId(queue->GetDexFieldIndex()).type_idx_,
java_lang_ref_ReferenceQueue->GetDexTypeIndex());
- Field* queueNext = java_lang_ref_Reference->GetInstanceField(2);
+ mirror::Field* queueNext = java_lang_ref_Reference->GetInstanceField(2);
fh.ChangeField(queueNext);
CHECK_STREQ(fh.GetName(), "queueNext");
CHECK_EQ(java_lang_dex.GetFieldId(queueNext->GetDexFieldIndex()).type_idx_,
java_lang_ref_Reference->GetDexTypeIndex());
- Field* referent = java_lang_ref_Reference->GetInstanceField(3);
+ mirror::Field* referent = java_lang_ref_Reference->GetInstanceField(3);
fh.ChangeField(referent);
CHECK_STREQ(fh.GetName(), "referent");
CHECK_EQ(java_lang_dex.GetFieldId(referent->GetDexFieldIndex()).type_idx_,
GetClassRoot(kJavaLangObject)->GetDexTypeIndex());
- Field* zombie = java_lang_ref_FinalizerReference->GetInstanceField(2);
+ mirror::Field* zombie = java_lang_ref_FinalizerReference->GetInstanceField(2);
fh.ChangeField(zombie);
CHECK_STREQ(fh.GetName(), "zombie");
CHECK_EQ(java_lang_dex.GetFieldId(zombie->GetDexFieldIndex()).type_idx_,
@@ -578,7 +593,7 @@
// ensure all class_roots_ are initialized
for (size_t i = 0; i < kClassRootsMax; i++) {
ClassRoot class_root = static_cast<ClassRoot>(i);
- Class* klass = GetClassRoot(class_root);
+ mirror::Class* klass = GetClassRoot(class_root);
CHECK(klass != NULL);
DCHECK(klass->IsArrayClass() || klass->IsPrimitive() || klass->GetDexCache() != NULL);
// note SetClassRoot does additional validation.
@@ -597,7 +612,7 @@
void ClassLinker::RunRootClinits() {
Thread* self = Thread::Current();
for (size_t i = 0; i < ClassLinker::kClassRootsMax; ++i) {
- Class* c = GetClassRoot(ClassRoot(i));
+ mirror::Class* c = GetClassRoot(ClassRoot(i));
if (!c->IsArrayClass() && !c->IsPrimitive()) {
EnsureInitialized(GetClassRoot(ClassRoot(i)), true, true);
self->AssertNoPendingException();
@@ -699,7 +714,8 @@
const ImageHeader& image_header = space->GetImageHeader();
// Grab location but don't use Object::AsString as we haven't yet initialized the roots to
// check the down cast
- String* oat_location = down_cast<String*>(image_header.GetImageRoot(ImageHeader::kOatLocation));
+ mirror::String* oat_location =
+ down_cast<mirror::String*>(image_header.GetImageRoot(ImageHeader::kOatLocation));
std::string oat_filename;
oat_filename += runtime->GetHostPrefix();
oat_filename += oat_location->ToModifiedUtf8();
@@ -971,21 +987,22 @@
CHECK_EQ(oat_file->GetOatHeader().GetImageFileLocationOatChecksum(), 0U);
CHECK_EQ(oat_file->GetOatHeader().GetImageFileLocationOatDataBegin(), 0U);
CHECK(oat_file->GetOatHeader().GetImageFileLocation().empty());
- Object* dex_caches_object = space->GetImageHeader().GetImageRoot(ImageHeader::kDexCaches);
- ObjectArray<DexCache>* dex_caches = dex_caches_object->AsObjectArray<DexCache>();
+ mirror::Object* dex_caches_object = space->GetImageHeader().GetImageRoot(ImageHeader::kDexCaches);
+ mirror::ObjectArray<mirror::DexCache>* dex_caches =
+ dex_caches_object->AsObjectArray<mirror::DexCache>();
- ObjectArray<Class>* class_roots =
- space->GetImageHeader().GetImageRoot(ImageHeader::kClassRoots)->AsObjectArray<Class>();
+ mirror::ObjectArray<mirror::Class>* class_roots =
+ space->GetImageHeader().GetImageRoot(ImageHeader::kClassRoots)->AsObjectArray<mirror::Class>();
// Special case of setting up the String class early so that we can test arbitrary objects
// as being Strings or not
- String::SetClass(class_roots->Get(kJavaLangString));
+ mirror::String::SetClass(class_roots->Get(kJavaLangString));
CHECK_EQ(oat_file->GetOatHeader().GetDexFileCount(),
static_cast<uint32_t>(dex_caches->GetLength()));
Thread* self = Thread::Current();
for (int i = 0; i < dex_caches->GetLength(); i++) {
- SirtRef<DexCache> dex_cache(self, dex_caches->Get(i));
+ SirtRef<mirror::DexCache> dex_cache(self, dex_caches->Get(i));
const std::string& dex_file_location(dex_cache->GetLocation()->ToModifiedUtf8());
const OatFile::OatDexFile* oat_dex_file = oat_file->GetOatDexFile(dex_file_location);
CHECK(oat_dex_file != NULL) << oat_file->GetLocation() << " " << dex_file_location;
@@ -1008,33 +1025,33 @@
}
// reinit class_roots_
- Class::SetClassClass(class_roots->Get(kJavaLangClass));
+ mirror::Class::SetClassClass(class_roots->Get(kJavaLangClass));
class_roots_ = class_roots;
// reinit array_iftable_ from any array class instance, they should be ==
array_iftable_ = GetClassRoot(kObjectArrayClass)->GetIfTable();
DCHECK(array_iftable_ == GetClassRoot(kBooleanArrayClass)->GetIfTable());
// String class root was set above
- Field::SetClass(GetClassRoot(kJavaLangReflectField));
- AbstractMethod::SetClasses(GetClassRoot(kJavaLangReflectConstructor),
+ mirror::Field::SetClass(GetClassRoot(kJavaLangReflectField));
+ mirror::AbstractMethod::SetClasses(GetClassRoot(kJavaLangReflectConstructor),
GetClassRoot(kJavaLangReflectMethod));
- BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
- ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
- CharArray::SetArrayClass(GetClassRoot(kCharArrayClass));
- DoubleArray::SetArrayClass(GetClassRoot(kDoubleArrayClass));
- FloatArray::SetArrayClass(GetClassRoot(kFloatArrayClass));
- IntArray::SetArrayClass(GetClassRoot(kIntArrayClass));
- LongArray::SetArrayClass(GetClassRoot(kLongArrayClass));
- ShortArray::SetArrayClass(GetClassRoot(kShortArrayClass));
- Throwable::SetClass(GetClassRoot(kJavaLangThrowable));
- StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
+ mirror::BooleanArray::SetArrayClass(GetClassRoot(kBooleanArrayClass));
+ mirror::ByteArray::SetArrayClass(GetClassRoot(kByteArrayClass));
+ mirror::CharArray::SetArrayClass(GetClassRoot(kCharArrayClass));
+ mirror::DoubleArray::SetArrayClass(GetClassRoot(kDoubleArrayClass));
+ mirror::FloatArray::SetArrayClass(GetClassRoot(kFloatArrayClass));
+ mirror::IntArray::SetArrayClass(GetClassRoot(kIntArrayClass));
+ mirror::LongArray::SetArrayClass(GetClassRoot(kLongArrayClass));
+ mirror::ShortArray::SetArrayClass(GetClassRoot(kShortArrayClass));
+ mirror::Throwable::SetClass(GetClassRoot(kJavaLangThrowable));
+ mirror::StackTraceElement::SetClass(GetClassRoot(kJavaLangStackTraceElement));
FinishInit();
VLOG(startup) << "ClassLinker::InitFromImage exiting";
}
-void ClassLinker::InitFromImageCallback(Object* obj, void* arg) {
+void ClassLinker::InitFromImageCallback(mirror::Object* obj, void* arg) {
DCHECK(obj != NULL);
DCHECK(arg != NULL);
ClassLinker* class_linker = reinterpret_cast<ClassLinker*>(arg);
@@ -1045,9 +1062,9 @@
}
if (obj->IsClass()) {
// restore class to ClassLinker::classes_ table
- Class* klass = obj->AsClass();
+ mirror::Class* klass = obj->AsClass();
ClassHelper kh(klass, class_linker);
- Class* existing = class_linker->InsertClass(kh.GetDescriptor(), klass, true);
+ mirror::Class* existing = class_linker->InsertClass(kh.GetDescriptor(), klass, true);
DCHECK(existing == NULL) << kh.GetDescriptor();
return;
}
@@ -1056,7 +1073,7 @@
// Keep in sync with InitCallback. Anything we visit, we need to
// reinit references to when reinitializing a ClassLinker from a
// mapped image.
-void ClassLinker::VisitRoots(Heap::RootVisitor* visitor, void* arg) {
+void ClassLinker::VisitRoots(RootVisitor* visitor, void* arg) {
visitor(class_roots_, arg);
Thread* self = Thread::Current();
{
@@ -1096,16 +1113,16 @@
}
}
-static bool GetClassesVisitor(Class* c, void* arg) {
- std::set<Class*>* classes = reinterpret_cast<std::set<Class*>*>(arg);
+static bool GetClassesVisitor(mirror::Class* c, void* arg) {
+ std::set<mirror::Class*>* classes = reinterpret_cast<std::set<mirror::Class*>*>(arg);
classes->insert(c);
return true;
}
void ClassLinker::VisitClassesWithoutClassesLock(ClassVisitor* visitor, void* arg) const {
- std::set<Class*> classes;
+ std::set<mirror::Class*> classes;
VisitClasses(GetClassesVisitor, &classes);
- typedef std::set<Class*>::const_iterator It; // TODO: C++0x auto
+ typedef std::set<mirror::Class*>::const_iterator It; // TODO: C++0x auto
for (It it = classes.begin(), end = classes.end(); it != end; ++it) {
if (!visitor(*it, arg)) {
return;
@@ -1115,57 +1132,61 @@
ClassLinker::~ClassLinker() {
- Class::ResetClass();
- String::ResetClass();
- Field::ResetClass();
- AbstractMethod::ResetClasses();
- BooleanArray::ResetArrayClass();
- ByteArray::ResetArrayClass();
- CharArray::ResetArrayClass();
- DoubleArray::ResetArrayClass();
- FloatArray::ResetArrayClass();
- IntArray::ResetArrayClass();
- LongArray::ResetArrayClass();
- ShortArray::ResetArrayClass();
- Throwable::ResetClass();
- StackTraceElement::ResetClass();
+ mirror::Class::ResetClass();
+ mirror::String::ResetClass();
+ mirror::Field::ResetClass();
+ mirror::AbstractMethod::ResetClasses();
+ mirror::BooleanArray::ResetArrayClass();
+ mirror::ByteArray::ResetArrayClass();
+ mirror::CharArray::ResetArrayClass();
+ mirror::DoubleArray::ResetArrayClass();
+ mirror::FloatArray::ResetArrayClass();
+ mirror::IntArray::ResetArrayClass();
+ mirror::LongArray::ResetArrayClass();
+ mirror::ShortArray::ResetArrayClass();
+ mirror::Throwable::ResetClass();
+ mirror::StackTraceElement::ResetClass();
STLDeleteElements(&boot_class_path_);
STLDeleteElements(&oat_files_);
}
-DexCache* ClassLinker::AllocDexCache(Thread* self, const DexFile& dex_file) {
+mirror::DexCache* ClassLinker::AllocDexCache(Thread* self, const DexFile& dex_file) {
Heap* heap = Runtime::Current()->GetHeap();
- Class* dex_cache_class = GetClassRoot(kJavaLangDexCache);
- SirtRef<DexCache> dex_cache(self,
- down_cast<DexCache*>(heap->AllocObject(self, dex_cache_class,
- dex_cache_class->GetObjectSize())));
+ mirror::Class* dex_cache_class = GetClassRoot(kJavaLangDexCache);
+ SirtRef<mirror::DexCache> dex_cache(self,
+ down_cast<mirror::DexCache*>(heap->AllocObject(self, dex_cache_class,
+ dex_cache_class->GetObjectSize())));
if (dex_cache.get() == NULL) {
return NULL;
}
- SirtRef<String> location(self, intern_table_->InternStrong(dex_file.GetLocation().c_str()));
+ SirtRef<mirror::String>
+ location(self, intern_table_->InternStrong(dex_file.GetLocation().c_str()));
if (location.get() == NULL) {
return NULL;
}
- SirtRef<ObjectArray<String> > strings(self, AllocStringArray(self, dex_file.NumStringIds()));
+ SirtRef<mirror::ObjectArray<mirror::String> >
+ strings(self, AllocStringArray(self, dex_file.NumStringIds()));
if (strings.get() == NULL) {
return NULL;
}
- SirtRef<ObjectArray<Class> > types(self, AllocClassArray(self, dex_file.NumTypeIds()));
+ SirtRef<mirror::ObjectArray<mirror::Class> >
+ types(self, AllocClassArray(self, dex_file.NumTypeIds()));
if (types.get() == NULL) {
return NULL;
}
- SirtRef<ObjectArray<AbstractMethod> >
+ SirtRef<mirror::ObjectArray<mirror::AbstractMethod> >
methods(self, AllocAbstractMethodArray(self, dex_file.NumMethodIds()));
if (methods.get() == NULL) {
return NULL;
}
- SirtRef<ObjectArray<Field> > fields(self, AllocFieldArray(self, dex_file.NumFieldIds()));
+ SirtRef<mirror::ObjectArray<mirror::Field> >
+ fields(self, AllocFieldArray(self, dex_file.NumFieldIds()));
if (fields.get() == NULL) {
return NULL;
}
- SirtRef<ObjectArray<StaticStorageBase> >
+ SirtRef<mirror::ObjectArray<mirror::StaticStorageBase> >
initialized_static_storage(self,
- AllocObjectArray<StaticStorageBase>(self, dex_file.NumTypeIds()));
+ AllocObjectArray<mirror::StaticStorageBase>(self, dex_file.NumTypeIds()));
if (initialized_static_storage.get() == NULL) {
return NULL;
}
@@ -1180,40 +1201,41 @@
return dex_cache.get();
}
-Class* ClassLinker::AllocClass(Thread* self, Class* java_lang_Class, size_t class_size) {
- DCHECK_GE(class_size, sizeof(Class));
+mirror::Class* ClassLinker::AllocClass(Thread* self, mirror::Class* java_lang_Class,
+ size_t class_size) {
+ DCHECK_GE(class_size, sizeof(mirror::Class));
Heap* heap = Runtime::Current()->GetHeap();
- SirtRef<Class> klass(self,
+ SirtRef<mirror::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(Thread* self, size_t class_size) {
+mirror::Class* ClassLinker::AllocClass(Thread* self, size_t class_size) {
return AllocClass(self, GetClassRoot(kJavaLangClass), class_size);
}
-Field* ClassLinker::AllocField(Thread* self) {
- return down_cast<Field*>(GetClassRoot(kJavaLangReflectField)->AllocObject(self));
+mirror::Field* ClassLinker::AllocField(Thread* self) {
+ return down_cast<mirror::Field*>(GetClassRoot(kJavaLangReflectField)->AllocObject(self));
}
-Method* ClassLinker::AllocMethod(Thread* self) {
- return down_cast<Method*>(GetClassRoot(kJavaLangReflectMethod)->AllocObject(self));
+mirror::Method* ClassLinker::AllocMethod(Thread* self) {
+ return down_cast<mirror::Method*>(GetClassRoot(kJavaLangReflectMethod)->AllocObject(self));
}
-Constructor* ClassLinker::AllocConstructor(Thread* self) {
- return down_cast<Constructor*>(GetClassRoot(kJavaLangReflectConstructor)->AllocObject(self));
+mirror::Constructor* ClassLinker::AllocConstructor(Thread* self) {
+ return down_cast<mirror::Constructor*>(GetClassRoot(kJavaLangReflectConstructor)->AllocObject(self));
}
-ObjectArray<StackTraceElement>* ClassLinker::AllocStackTraceElementArray(Thread* self,
- size_t length) {
- return ObjectArray<StackTraceElement>::Alloc(self,
- GetClassRoot(kJavaLangStackTraceElementArrayClass),
- length);
+mirror::ObjectArray<mirror::StackTraceElement>* ClassLinker::AllocStackTraceElementArray(Thread* self,
+ size_t length) {
+ return mirror::ObjectArray<mirror::StackTraceElement>::Alloc(self,
+ GetClassRoot(kJavaLangStackTraceElementArrayClass),
+ length);
}
-static Class* EnsureResolved(Thread* self, Class* klass)
+static mirror::Class* EnsureResolved(Thread* self, mirror::Class* klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(klass != NULL);
// Wait for the class if it has not already been linked.
@@ -1223,7 +1245,7 @@
if (!klass->IsResolved() && klass->GetClinitThreadId() == self->GetTid()) {
self->ThrowNewException("Ljava/lang/ClassCircularityError;",
PrettyDescriptor(klass).c_str());
- klass->SetStatus(Class::kStatusError);
+ klass->SetStatus(mirror::Class::kStatusError);
return NULL;
}
// Wait for the pending initialization to complete.
@@ -1243,11 +1265,11 @@
return klass;
}
-Class* ClassLinker::FindSystemClass(const char* descriptor) {
+mirror::Class* ClassLinker::FindSystemClass(const char* descriptor) {
return FindClass(descriptor, NULL);
}
-Class* ClassLinker::FindClass(const char* descriptor, ClassLoader* class_loader) {
+mirror::Class* ClassLinker::FindClass(const char* descriptor, mirror::ClassLoader* class_loader) {
DCHECK_NE(*descriptor, '\0') << "descriptor is empty string";
Thread* self = Thread::Current();
DCHECK(self != NULL);
@@ -1258,7 +1280,7 @@
return FindPrimitiveClass(descriptor[0]);
}
// Find the class in the loaded classes table.
- Class* klass = LookupClass(descriptor, class_loader);
+ mirror::Class* klass = LookupClass(descriptor, class_loader);
if (klass != NULL) {
return EnsureResolved(self, klass);
}
@@ -1274,7 +1296,7 @@
} else if (Runtime::Current()->UseCompileTimeClassPath()) {
// first try the boot class path
- Class* system_class = FindSystemClass(descriptor);
+ mirror::Class* system_class = FindSystemClass(descriptor);
if (system_class != NULL) {
return system_class;
}
@@ -1321,8 +1343,8 @@
class_name_string.c_str());
return NULL;
} else {
- // success, return Class*
- return soa.Decode<Class*>(result.get());
+ // success, return mirror::Class*
+ return soa.Decode<mirror::Class*>(result.get());
}
}
@@ -1330,12 +1352,12 @@
return NULL;
}
-Class* ClassLinker::DefineClass(const StringPiece& descriptor,
- ClassLoader* class_loader,
- const DexFile& dex_file,
- const DexFile::ClassDef& dex_class_def) {
+mirror::Class* ClassLinker::DefineClass(const StringPiece& descriptor,
+ mirror::ClassLoader* class_loader,
+ const DexFile& dex_file,
+ const DexFile::ClassDef& dex_class_def) {
Thread* self = Thread::Current();
- SirtRef<Class> klass(self, NULL);
+ SirtRef<mirror::Class> klass(self, NULL);
// Load the class from the dex file.
if (!init_done_) {
// finish up init of hand crafted class_roots_
@@ -1365,13 +1387,13 @@
LoadClass(dex_file, dex_class_def, klass, class_loader);
// Check for a pending exception during load
if (self->IsExceptionPending()) {
- klass->SetStatus(Class::kStatusError);
+ klass->SetStatus(mirror::Class::kStatusError);
return NULL;
}
ObjectLock lock(self, klass.get());
klass->SetClinitThreadId(self->GetTid());
// Add the newly loaded class to the loaded classes table.
- SirtRef<Class> existing(self, InsertClass(descriptor, klass.get(), false));
+ SirtRef<mirror::Class> existing(self, InsertClass(descriptor, klass.get(), false));
if (existing.get() != NULL) {
// We failed to insert because we raced with another thread.
return EnsureResolved(self, existing.get());
@@ -1380,7 +1402,7 @@
CHECK(!klass->IsLoaded());
if (!LoadSuperAndInterfaces(klass, dex_file)) {
// Loading failed.
- klass->SetStatus(Class::kStatusError);
+ klass->SetStatus(mirror::Class::kStatusError);
lock.NotifyAll();
return NULL;
}
@@ -1389,7 +1411,7 @@
CHECK(!klass->IsResolved());
if (!LinkClass(klass, NULL)) {
// Linking failed.
- klass->SetStatus(Class::kStatusError);
+ klass->SetStatus(mirror::Class::kStatusError);
lock.NotifyAll();
return NULL;
}
@@ -1433,7 +1455,7 @@
}
}
// start with generic class data
- size_t size = sizeof(Class);
+ size_t size = sizeof(mirror::Class);
// follow with reference fields which must be contiguous at start
size += (num_ref * sizeof(uint32_t));
// if there are 64-bit fields to add, make sure they are aligned
@@ -1502,10 +1524,10 @@
return 0;
}
-const OatFile::OatMethod ClassLinker::GetOatMethodFor(const AbstractMethod* method) {
+const OatFile::OatMethod ClassLinker::GetOatMethodFor(const mirror::AbstractMethod* method) {
// Although we overwrite the trampoline of non-static methods, we may get here via the resolution
// method for direct methods (or virtual methods made direct).
- Class* declaring_class = method->GetDeclaringClass();
+ mirror::Class* declaring_class = method->GetDeclaringClass();
size_t oat_method_index;
if (method->IsStatic() || method->IsDirect()) {
// Simple case where the oat method index was stashed at load time.
@@ -1536,7 +1558,7 @@
}
// Special case to get oat code without overwriting a trampoline.
-const void* ClassLinker::GetOatCodeFor(const AbstractMethod* method) {
+const void* ClassLinker::GetOatCodeFor(const mirror::AbstractMethod* method) {
CHECK(Runtime::Current()->IsCompiler() || method->GetDeclaringClass()->IsInitializing());
return GetOatMethodFor(method).GetCode();
}
@@ -1550,7 +1572,7 @@
return oat_class->GetOatMethod(oat_method_idx).GetCode();
}
-void ClassLinker::FixupStaticTrampolines(Class* klass) {
+void ClassLinker::FixupStaticTrampolines(mirror::Class* klass) {
ClassHelper kh(klass);
const DexFile::ClassDef* dex_class_def = kh.GetClassDef();
CHECK(dex_class_def != NULL);
@@ -1577,7 +1599,7 @@
// Link the code of methods skipped by LinkCode
const void* trampoline = Runtime::Current()->GetResolutionStubArray(Runtime::kStaticMethod)->GetData();
for (size_t i = 0; it.HasNextDirectMethod(); i++, it.Next()) {
- AbstractMethod* method = klass->GetDirectMethod(i);
+ mirror::AbstractMethod* method = klass->GetDirectMethod(i);
if (Runtime::Current()->IsMethodTracingActive()) {
Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
if (instrumentation->GetSavedCodeFromMap(method) == trampoline) {
@@ -1596,7 +1618,7 @@
}
}
-static void LinkCode(SirtRef<AbstractMethod>& method, const OatFile::OatClass* oat_class,
+static void LinkCode(SirtRef<mirror::AbstractMethod>& method, const OatFile::OatClass* oat_class,
uint32_t method_index)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Every kind of method should at least get an invoke stub from the oat_method.
@@ -1627,11 +1649,11 @@
void ClassLinker::LoadClass(const DexFile& dex_file,
const DexFile::ClassDef& dex_class_def,
- SirtRef<Class>& klass,
- ClassLoader* class_loader) {
+ SirtRef<mirror::Class>& klass,
+ mirror::ClassLoader* class_loader) {
CHECK(klass.get() != NULL);
CHECK(klass->GetDexCache() != NULL);
- CHECK_EQ(Class::kStatusNotReady, klass->GetStatus());
+ CHECK_EQ(mirror::Class::kStatusNotReady, klass->GetStatus());
const char* descriptor = dex_file.GetClassDescriptor(dex_class_def);
CHECK(descriptor != NULL);
@@ -1643,7 +1665,7 @@
klass->SetAccessFlags(access_flags);
klass->SetClassLoader(class_loader);
DCHECK_EQ(klass->GetPrimitiveType(), Primitive::kPrimNot);
- klass->SetStatus(Class::kStatusIdx);
+ klass->SetStatus(mirror::Class::kStatusIdx);
klass->SetDexTypeIndex(dex_class_def.class_idx_);
@@ -1661,12 +1683,12 @@
klass->SetIFields(AllocFieldArray(self, it.NumInstanceFields()));
}
for (size_t i = 0; it.HasNextStaticField(); i++, it.Next()) {
- SirtRef<Field> sfield(self, AllocField(self));
+ SirtRef<mirror::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(self));
+ SirtRef<mirror::Field> ifield(self, AllocField(self));
klass->SetInstanceField(i, ifield.get());
LoadField(dex_file, it, klass, ifield);
}
@@ -1687,7 +1709,7 @@
}
size_t class_def_method_index = 0;
for (size_t i = 0; it.HasNextDirectMethod(); i++, it.Next()) {
- SirtRef<AbstractMethod> method(self, LoadMethod(self, dex_file, it, klass));
+ SirtRef<mirror::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);
@@ -1696,7 +1718,7 @@
class_def_method_index++;
}
for (size_t i = 0; it.HasNextVirtualMethod(); i++, it.Next()) {
- SirtRef<AbstractMethod> method(self, LoadMethod(self, dex_file, it, klass));
+ SirtRef<mirror::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) {
@@ -1708,21 +1730,21 @@
}
void ClassLinker::LoadField(const DexFile& /*dex_file*/, const ClassDataItemIterator& it,
- SirtRef<Class>& klass, SirtRef<Field>& dst) {
+ SirtRef<mirror::Class>& klass, SirtRef<mirror::Field>& dst) {
uint32_t field_idx = it.GetMemberIndex();
dst->SetDexFieldIndex(field_idx);
dst->SetDeclaringClass(klass.get());
dst->SetAccessFlags(it.GetMemberAccessFlags());
}
-AbstractMethod* ClassLinker::LoadMethod(Thread* self, const DexFile& dex_file,
- const ClassDataItemIterator& it,
- SirtRef<Class>& klass) {
+mirror::AbstractMethod* ClassLinker::LoadMethod(Thread* self, const DexFile& dex_file,
+ const ClassDataItemIterator& it,
+ SirtRef<mirror::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;
+ mirror::AbstractMethod* dst = NULL;
if (method_name == "<init>") {
dst = AllocConstructor(self);
} else {
@@ -1780,11 +1802,11 @@
void ClassLinker::AppendToBootClassPath(const DexFile& dex_file) {
Thread* self = Thread::Current();
- SirtRef<DexCache> dex_cache(self, AllocDexCache(self, dex_file));
+ SirtRef<mirror::DexCache> dex_cache(self, AllocDexCache(self, dex_file));
AppendToBootClassPath(dex_file, dex_cache);
}
-void ClassLinker::AppendToBootClassPath(const DexFile& dex_file, SirtRef<DexCache>& dex_cache) {
+void ClassLinker::AppendToBootClassPath(const DexFile& dex_file, SirtRef<mirror::DexCache>& dex_cache) {
CHECK(dex_cache.get() != NULL) << dex_file.GetLocation();
boot_class_path_.push_back(&dex_file);
RegisterDexFile(dex_file, dex_cache);
@@ -1805,7 +1827,7 @@
return IsDexFileRegisteredLocked(dex_file);
}
-void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file, SirtRef<DexCache>& dex_cache) {
+void ClassLinker::RegisterDexFileLocked(const DexFile& dex_file, SirtRef<mirror::DexCache>& dex_cache) {
dex_lock_.AssertHeld(Thread::Current());
CHECK(dex_cache.get() != NULL) << dex_file.GetLocation();
CHECK(dex_cache->GetLocation()->Equals(dex_file.GetLocation()));
@@ -1825,7 +1847,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(self, dex_file));
+ SirtRef<mirror::DexCache> dex_cache(self, AllocDexCache(self, dex_file));
{
MutexLock mu(self, dex_lock_);
if (IsDexFileRegisteredLocked(dex_file)) {
@@ -1835,16 +1857,16 @@
}
}
-void ClassLinker::RegisterDexFile(const DexFile& dex_file, SirtRef<DexCache>& dex_cache) {
+void ClassLinker::RegisterDexFile(const DexFile& dex_file, SirtRef<mirror::DexCache>& dex_cache) {
MutexLock mu(Thread::Current(), dex_lock_);
RegisterDexFileLocked(dex_file, dex_cache);
}
-DexCache* ClassLinker::FindDexCache(const DexFile& dex_file) const {
+mirror::DexCache* ClassLinker::FindDexCache(const DexFile& dex_file) const {
MutexLock mu(Thread::Current(), dex_lock_);
// Search assuming unique-ness of dex file.
for (size_t i = 0; i != dex_caches_.size(); ++i) {
- DexCache* dex_cache = dex_caches_[i];
+ mirror::DexCache* dex_cache = dex_caches_[i];
if (dex_cache->GetDexFile() == &dex_file) {
return dex_cache;
}
@@ -1852,35 +1874,39 @@
// Search matching by location name.
std::string location(dex_file.GetLocation());
for (size_t i = 0; i != dex_caches_.size(); ++i) {
- DexCache* dex_cache = dex_caches_[i];
+ mirror::DexCache* dex_cache = dex_caches_[i];
if (dex_cache->GetDexFile()->GetLocation() == location) {
return dex_cache;
}
}
// Failure, dump diagnostic and abort.
for (size_t i = 0; i != dex_caches_.size(); ++i) {
- DexCache* dex_cache = dex_caches_[i];
+ mirror::DexCache* dex_cache = dex_caches_[i];
LOG(ERROR) << "Registered dex file " << i << " = " << dex_cache->GetDexFile()->GetLocation();
}
LOG(FATAL) << "Failed to find DexCache for DexFile " << location;
return NULL;
}
-void ClassLinker::FixupDexCaches(AbstractMethod* resolution_method) const {
+void ClassLinker::FixupDexCaches(mirror::AbstractMethod* resolution_method) const {
MutexLock mu(Thread::Current(), dex_lock_);
for (size_t i = 0; i != dex_caches_.size(); ++i) {
dex_caches_[i]->Fixup(resolution_method);
}
}
-Class* ClassLinker::InitializePrimitiveClass(Class* primitive_class, Primitive::Type type) {
+mirror::Class* ClassLinker::CreatePrimitiveClass(Thread* self, Primitive::Type type) {
+ return InitializePrimitiveClass(AllocClass(self, sizeof(mirror::Class)), type);
+}
+
+mirror::Class* ClassLinker::InitializePrimitiveClass(mirror::Class* primitive_class, Primitive::Type type) {
CHECK(primitive_class != NULL);
// Must hold lock on object when initializing.
ObjectLock lock(Thread::Current(), primitive_class);
primitive_class->SetAccessFlags(kAccPublic | kAccFinal | kAccAbstract);
primitive_class->SetPrimitiveType(type);
- primitive_class->SetStatus(Class::kStatusInitialized);
- Class* existing = InsertClass(Primitive::Descriptor(type), primitive_class, false);
+ primitive_class->SetStatus(mirror::Class::kStatusInitialized);
+ mirror::Class* existing = InsertClass(Primitive::Descriptor(type), primitive_class, false);
CHECK(existing == NULL) << "InitPrimitiveClass(" << type << ") failed";
return primitive_class;
}
@@ -1898,11 +1924,12 @@
// array class; that always comes from the base element class.
//
// Returns NULL with an exception raised on failure.
-Class* ClassLinker::CreateArrayClass(const std::string& descriptor, ClassLoader* class_loader) {
+mirror::Class* ClassLinker::CreateArrayClass(const std::string& descriptor,
+ mirror::ClassLoader* class_loader) {
CHECK_EQ('[', descriptor[0]);
// Identify the underlying component type
- Class* component_type = FindClass(descriptor.substr(1).c_str(), class_loader);
+ mirror::Class* component_type = FindClass(descriptor.substr(1).c_str(), class_loader);
if (component_type == NULL) {
DCHECK(Thread::Current()->IsExceptionPending());
return NULL;
@@ -1926,7 +1953,7 @@
// class to the hash table --- necessary because of possible races with
// other threads.)
if (class_loader != component_type->GetClassLoader()) {
- Class* new_class = LookupClass(descriptor.c_str(), component_type->GetClassLoader());
+ mirror::Class* new_class = LookupClass(descriptor.c_str(), component_type->GetClassLoader());
if (new_class != NULL) {
return new_class;
}
@@ -1941,7 +1968,7 @@
// Array classes are simple enough that we don't need to do a full
// link step.
Thread* self = Thread::Current();
- SirtRef<Class> new_class(self, NULL);
+ SirtRef<mirror::Class> new_class(self, NULL);
if (!init_done_) {
// Classes that were hand created, ie not by FindSystemClass
if (descriptor == "[Ljava/lang/Class;") {
@@ -1963,7 +1990,7 @@
}
}
if (new_class.get() == NULL) {
- new_class.reset(AllocClass(self, sizeof(Class)));
+ new_class.reset(AllocClass(self, sizeof(mirror::Class)));
if (new_class.get() == NULL) {
return NULL;
}
@@ -1971,12 +1998,12 @@
}
ObjectLock lock(self, new_class.get()); // Must hold lock on object when initializing.
DCHECK(new_class->GetComponentType() != NULL);
- Class* java_lang_Object = GetClassRoot(kJavaLangObject);
+ mirror::Class* java_lang_Object = GetClassRoot(kJavaLangObject);
new_class->SetSuperClass(java_lang_Object);
new_class->SetVTable(java_lang_Object->GetVTable());
new_class->SetPrimitiveType(Primitive::kPrimNot);
new_class->SetClassLoader(component_type->GetClassLoader());
- new_class->SetStatus(Class::kStatusInitialized);
+ new_class->SetStatus(mirror::Class::kStatusInitialized);
// don't need to set new_class->SetObjectSize(..)
// because Object::SizeOf delegates to Array::SizeOf
@@ -2006,7 +2033,7 @@
new_class->SetAccessFlags(((new_class->GetComponentType()->GetAccessFlags() &
~kAccInterface) | kAccFinal) & kAccJavaFlagsMask);
- Class* existing = InsertClass(descriptor, new_class.get(), false);
+ mirror::Class* existing = InsertClass(descriptor, new_class.get(), false);
if (existing == NULL) {
return new_class.get();
}
@@ -2019,7 +2046,7 @@
return existing;
}
-Class* ClassLinker::FindPrimitiveClass(char type) {
+mirror::Class* ClassLinker::FindPrimitiveClass(char type) {
switch (Primitive::GetType(type)) {
case Primitive::kPrimByte:
return GetClassRoot(kPrimitiveByte);
@@ -2047,9 +2074,9 @@
return NULL;
}
-Class* ClassLinker::InsertClass(const StringPiece& descriptor, Class* klass, bool image_class) {
+mirror::Class* ClassLinker::InsertClass(const StringPiece& descriptor, mirror::Class* klass, bool image_class) {
if (VLOG_IS_ON(class_linker)) {
- DexCache* dex_cache = klass->GetDexCache();
+ mirror::DexCache* dex_cache = klass->GetDexCache();
std::string source;
if (dex_cache != NULL) {
source += " from ";
@@ -2060,7 +2087,7 @@
size_t hash = StringPieceHash()(descriptor);
MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
Table& classes = image_class ? image_classes_ : classes_;
- Class* existing = LookupClassLocked(descriptor.data(), klass->GetClassLoader(), hash, classes);
+ mirror::Class* existing = LookupClassLocked(descriptor.data(), klass->GetClassLoader(), hash, classes);
#ifndef NDEBUG
// Check we don't have the class in the other table in error
Table& other_classes = image_class ? classes_ : image_classes_;
@@ -2074,22 +2101,24 @@
return NULL;
}
-bool ClassLinker::RemoveClass(const char* descriptor, const ClassLoader* class_loader) {
+bool ClassLinker::RemoveClass(const char* descriptor, const mirror::ClassLoader* class_loader) {
size_t hash = Hash(descriptor);
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;
- for (It it = classes_.lower_bound(hash), end = classes_.end(); it != end && it->first == hash; ++it) {
- Class* klass = it->second;
+ for (It it = classes_.lower_bound(hash), end = classes_.end(); it != end && it->first == hash;
+ ++it) {
+ mirror::Class* klass = it->second;
kh.ChangeClass(klass);
if (strcmp(kh.GetDescriptor(), descriptor) == 0 && klass->GetClassLoader() == class_loader) {
classes_.erase(it);
return true;
}
}
- for (It it = image_classes_.lower_bound(hash), end = classes_.end(); it != end && it->first == hash; ++it) {
- Class* klass = it->second;
+ for (It it = image_classes_.lower_bound(hash), end = classes_.end();
+ it != end && it->first == hash; ++it) {
+ mirror::Class* klass = it->second;
kh.ChangeClass(klass);
if (strcmp(kh.GetDescriptor(), descriptor) == 0 && klass->GetClassLoader() == class_loader) {
image_classes_.erase(it);
@@ -2099,28 +2128,30 @@
return false;
}
-Class* ClassLinker::LookupClass(const char* descriptor, const ClassLoader* class_loader) {
+mirror::Class* ClassLinker::LookupClass(const char* descriptor,
+ const mirror::ClassLoader* class_loader) {
size_t hash = Hash(descriptor);
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_);
+ mirror::Class* klass = LookupClassLocked(descriptor, class_loader, hash, classes_);
if (klass != NULL) {
return klass;
}
return LookupClassLocked(descriptor, class_loader, hash, image_classes_);
}
-Class* ClassLinker::LookupClassLocked(const char* descriptor, const ClassLoader* class_loader,
- size_t hash, const Table& classes) {
+mirror::Class* ClassLinker::LookupClassLocked(const char* descriptor,
+ const mirror::ClassLoader* class_loader,
+ size_t hash, const Table& classes) {
ClassHelper kh(NULL, this);
typedef Table::const_iterator It; // TODO: C++0x auto
for (It it = classes.lower_bound(hash), end = classes_.end(); it != end && it->first == hash; ++it) {
- Class* klass = it->second;
+ mirror::Class* klass = it->second;
kh.ChangeClass(klass);
if (strcmp(descriptor, kh.GetDescriptor()) == 0 && klass->GetClassLoader() == class_loader) {
#ifndef NDEBUG
for (++it; it != end && it->first == hash; ++it) {
- Class* klass2 = it->second;
+ mirror::Class* klass2 = it->second;
kh.ChangeClass(klass2);
CHECK(!(strcmp(descriptor, kh.GetDescriptor()) == 0 && klass2->GetClassLoader() == class_loader))
<< PrettyClass(klass) << " " << klass << " " << klass->GetClassLoader() << " "
@@ -2133,7 +2164,7 @@
return NULL;
}
-void ClassLinker::LookupClasses(const char* descriptor, std::vector<Class*>& classes) {
+void ClassLinker::LookupClasses(const char* descriptor, std::vector<mirror::Class*>& classes) {
classes.clear();
size_t hash = Hash(descriptor);
MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
@@ -2141,14 +2172,14 @@
// TODO: determine if its better to search classes_ or image_classes_ first
ClassHelper kh(NULL, this);
for (It it = classes_.lower_bound(hash), end = classes_.end(); it != end && it->first == hash; ++it) {
- Class* klass = it->second;
+ mirror::Class* klass = it->second;
kh.ChangeClass(klass);
if (strcmp(descriptor, kh.GetDescriptor()) == 0) {
classes.push_back(klass);
}
}
for (It it = image_classes_.lower_bound(hash), end = classes_.end(); it != end && it->first == hash; ++it) {
- Class* klass = it->second;
+ mirror::Class* klass = it->second;
kh.ChangeClass(klass);
if (strcmp(descriptor, kh.GetDescriptor()) == 0) {
classes.push_back(klass);
@@ -2156,7 +2187,7 @@
}
}
-void ClassLinker::VerifyClass(Class* klass) {
+void ClassLinker::VerifyClass(mirror::Class* klass) {
// TODO: assert that the monitor on the Class is held
Thread* self = Thread::Current();
ObjectLock lock(self, klass);
@@ -2174,16 +2205,17 @@
return;
}
- if (klass->GetStatus() == Class::kStatusResolved) {
- klass->SetStatus(Class::kStatusVerifying);
+ if (klass->GetStatus() == mirror::Class::kStatusResolved) {
+ klass->SetStatus(mirror::Class::kStatusVerifying);
} else {
- CHECK_EQ(klass->GetStatus(), Class::kStatusRetryVerificationAtRuntime) << PrettyClass(klass);
+ CHECK_EQ(klass->GetStatus(), mirror::Class::kStatusRetryVerificationAtRuntime)
+ << PrettyClass(klass);
CHECK(!Runtime::Current()->IsCompiler());
- klass->SetStatus(Class::kStatusVerifyingAtRuntime);
+ klass->SetStatus(mirror::Class::kStatusVerifyingAtRuntime);
}
// Verify super class.
- Class* super = klass->GetSuperClass();
+ mirror::Class* super = klass->GetSuperClass();
std::string error_msg;
if (super != NULL) {
// Acquire lock to prevent races on verifying the super class.
@@ -2198,7 +2230,7 @@
error_msg += " that attempts to sub-class erroneous class ";
error_msg += PrettyDescriptor(super);
LOG(ERROR) << error_msg << " in " << klass->GetDexCache()->GetLocation()->ToModifiedUtf8();
- SirtRef<Throwable> cause(self, self->GetException());
+ SirtRef<mirror::Throwable> cause(self, self->GetException());
if (cause.get() != NULL) {
self->ClearException();
}
@@ -2206,24 +2238,24 @@
if (cause.get() != NULL) {
self->GetException()->SetCause(cause.get());
}
- klass->SetStatus(Class::kStatusError);
+ klass->SetStatus(mirror::Class::kStatusError);
return;
}
}
// Try to use verification information from the oat file, otherwise do runtime verification.
const DexFile& dex_file = *klass->GetDexCache()->GetDexFile();
- Class::Status oat_file_class_status(Class::kStatusNotReady);
+ mirror::Class::Status oat_file_class_status(mirror::Class::kStatusNotReady);
bool preverified = VerifyClassUsingOatFile(dex_file, klass, oat_file_class_status);
verifier::MethodVerifier::FailureKind verifier_failure = verifier::MethodVerifier::kNoFailure;
- if (oat_file_class_status == Class::kStatusError) {
+ if (oat_file_class_status == mirror::Class::kStatusError) {
LOG(WARNING) << "Skipping runtime verification of erroneous class " << PrettyDescriptor(klass)
<< " in " << klass->GetDexCache()->GetLocation()->ToModifiedUtf8();
error_msg = "Rejecting class ";
error_msg += PrettyDescriptor(klass);
error_msg += " because it failed compile-time verification";
Thread::Current()->ThrowNewException("Ljava/lang/VerifyError;", error_msg.c_str());
- klass->SetStatus(Class::kStatusError);
+ klass->SetStatus(mirror::Class::kStatusError);
return;
}
if (!preverified) {
@@ -2239,16 +2271,16 @@
// Make sure all classes referenced by catch blocks are resolved.
ResolveClassExceptionHandlerTypes(dex_file, klass);
if (verifier_failure == verifier::MethodVerifier::kNoFailure) {
- klass->SetStatus(Class::kStatusVerified);
+ klass->SetStatus(mirror::Class::kStatusVerified);
} else {
CHECK_EQ(verifier_failure, verifier::MethodVerifier::kSoftFailure);
// Soft failures at compile time should be retried at runtime. Soft
// failures at runtime will be handled by slow paths in the generated
// code. Set status accordingly.
if (Runtime::Current()->IsCompiler()) {
- klass->SetStatus(Class::kStatusRetryVerificationAtRuntime);
+ klass->SetStatus(mirror::Class::kStatusRetryVerificationAtRuntime);
} else {
- klass->SetStatus(Class::kStatusVerified);
+ klass->SetStatus(mirror::Class::kStatusVerified);
}
}
} else {
@@ -2257,12 +2289,12 @@
<< " because: " << error_msg;
self->AssertNoPendingException();
self->ThrowNewException("Ljava/lang/VerifyError;", error_msg.c_str());
- klass->SetStatus(Class::kStatusError);
+ klass->SetStatus(mirror::Class::kStatusError);
}
}
-bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, Class* klass,
- Class::Status& oat_file_class_status) {
+bool ClassLinker::VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class* klass,
+ mirror::Class::Status& oat_file_class_status) {
if (!Runtime::Current()->IsStarted()) {
return false;
}
@@ -2281,11 +2313,11 @@
CHECK(oat_class.get() != NULL)
<< dex_file.GetLocation() << " " << PrettyClass(klass) << " " << descriptor;
oat_file_class_status = oat_class->GetStatus();
- if (oat_file_class_status == Class::kStatusVerified ||
- oat_file_class_status == Class::kStatusInitialized) {
+ if (oat_file_class_status == mirror::Class::kStatusVerified ||
+ oat_file_class_status == mirror::Class::kStatusInitialized) {
return true;
}
- if (oat_file_class_status == Class::kStatusRetryVerificationAtRuntime) {
+ if (oat_file_class_status == mirror::Class::kStatusRetryVerificationAtRuntime) {
// Compile time verification failed with a soft error. Compile time verification can fail
// because we have incomplete type information. Consider the following:
// class ... {
@@ -2305,12 +2337,12 @@
// at compile time).
return false;
}
- if (oat_file_class_status == Class::kStatusError) {
+ if (oat_file_class_status == mirror::Class::kStatusError) {
// Compile time verification failed with a hard error. This is caused by invalid instructions
// in the class. These errors are unrecoverable.
return false;
}
- if (oat_file_class_status == Class::kStatusNotReady) {
+ if (oat_file_class_status == mirror::Class::kStatusNotReady) {
// Status is uninitialized if we couldn't determine the status at compile time, for example,
// not loading the class.
// TODO: when the verifier doesn't rely on Class-es failing to resolve/load the type hierarchy
@@ -2323,7 +2355,7 @@
return false;
}
-void ClassLinker::ResolveClassExceptionHandlerTypes(const DexFile& dex_file, Class* klass) {
+void ClassLinker::ResolveClassExceptionHandlerTypes(const DexFile& dex_file, mirror::Class* klass) {
for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
ResolveMethodExceptionHandlerTypes(dex_file, klass->GetDirectMethod(i));
}
@@ -2332,7 +2364,8 @@
}
}
-void ClassLinker::ResolveMethodExceptionHandlerTypes(const DexFile& dex_file, AbstractMethod* method) {
+void ClassLinker::ResolveMethodExceptionHandlerTypes(const DexFile& dex_file,
+ mirror::AbstractMethod* method) {
// similar to DexVerifier::ScanTryCatchBlocks and dex2oat's ResolveExceptionsForMethod.
const DexFile::CodeItem* code_item = dex_file.GetCodeItem(method->GetCodeItemOffset());
if (code_item == NULL) {
@@ -2350,7 +2383,7 @@
// Ensure exception types are resolved so that they don't need resolution to be delivered,
// unresolved exception types will be ignored by exception delivery
if (iterator.GetHandlerTypeIndex() != DexFile::kDexNoIndex16) {
- Class* exception_type = linker->ResolveType(iterator.GetHandlerTypeIndex(), method);
+ mirror::Class* exception_type = linker->ResolveType(iterator.GetHandlerTypeIndex(), method);
if (exception_type == NULL) {
DCHECK(Thread::Current()->IsExceptionPending());
Thread::Current()->ClearException();
@@ -2361,26 +2394,29 @@
}
}
-static void CheckProxyConstructor(AbstractMethod* constructor);
-static void CheckProxyMethod(AbstractMethod* method, SirtRef<AbstractMethod>& prototype);
+static void CheckProxyConstructor(mirror::AbstractMethod* constructor);
+static void CheckProxyMethod(mirror::AbstractMethod* method,
+ SirtRef<mirror::AbstractMethod>& prototype);
-Class* ClassLinker::CreateProxyClass(String* name, ObjectArray<Class>* interfaces,
- ClassLoader* loader, ObjectArray<AbstractMethod>* methods,
- ObjectArray<ObjectArray<Class> >* throws) {
+mirror::Class* ClassLinker::CreateProxyClass(mirror::String* name,
+ mirror::ObjectArray<mirror::Class>* interfaces,
+ mirror::ClassLoader* loader,
+ mirror::ObjectArray<mirror::AbstractMethod>* methods,
+ mirror::ObjectArray<mirror::ObjectArray<mirror::Class> >* throws) {
Thread* self = Thread::Current();
- SirtRef<Class> klass(self, AllocClass(self, GetClassRoot(kJavaLangClass),
- sizeof(SynthesizedProxyClass)));
+ SirtRef<mirror::Class> klass(self, AllocClass(self, GetClassRoot(kJavaLangClass),
+ sizeof(mirror::SynthesizedProxyClass)));
CHECK(klass.get() != NULL);
DCHECK(klass->GetClass() != NULL);
- klass->SetObjectSize(sizeof(Proxy));
+ klass->SetObjectSize(sizeof(mirror::Proxy));
klass->SetAccessFlags(kAccClassIsProxy | kAccPublic | kAccFinal);
klass->SetClassLoader(loader);
DCHECK_EQ(klass->GetPrimitiveType(), Primitive::kPrimNot);
klass->SetName(name);
- Class* proxy_class = GetClassRoot(kJavaLangReflectProxy);
+ mirror::Class* proxy_class = GetClassRoot(kJavaLangReflectProxy);
klass->SetDexCache(proxy_class->GetDexCache());
- klass->SetStatus(Class::kStatusIdx);
+ klass->SetStatus(mirror::Class::kStatusIdx);
klass->SetDexTypeIndex(DexFile::kDexNoIndex16);
@@ -2388,13 +2424,13 @@
klass->SetSFields(AllocFieldArray(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(self));
+ SirtRef<mirror::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(self));
+ SirtRef<mirror::Field> throws_sfield(self, AllocField(self));
klass->SetStaticField(1, throws_sfield.get());
throws_sfield->SetDexFieldIndex(1);
throws_sfield->SetDeclaringClass(klass.get());
@@ -2408,24 +2444,24 @@
size_t num_virtual_methods = methods->GetLength();
klass->SetVirtualMethods(AllocMethodArray(self, num_virtual_methods));
for (size_t i = 0; i < num_virtual_methods; ++i) {
- SirtRef<AbstractMethod> prototype(self, methods->Get(i));
+ SirtRef<mirror::AbstractMethod> prototype(self, methods->Get(i));
klass->SetVirtualMethod(i, CreateProxyMethod(self, klass, prototype));
}
klass->SetSuperClass(proxy_class); // The super class is java.lang.reflect.Proxy
- klass->SetStatus(Class::kStatusLoaded); // Class is now effectively in the loaded state
+ klass->SetStatus(mirror::Class::kStatusLoaded); // Class is now effectively in the loaded state
DCHECK(!Thread::Current()->IsExceptionPending());
// Link the fields and virtual methods, creating vtable and iftables
if (!LinkClass(klass, interfaces)) {
- klass->SetStatus(Class::kStatusError);
+ klass->SetStatus(mirror::Class::kStatusError);
return NULL;
}
{
ObjectLock lock(self, klass.get()); // Must hold lock on object when initializing.
interfaces_sfield->SetObject(klass.get(), interfaces);
throws_sfield->SetObject(klass.get(), throws);
- klass->SetStatus(Class::kStatusInitialized);
+ klass->SetStatus(mirror::Class::kStatusInitialized);
}
// sanity checks
@@ -2433,7 +2469,7 @@
CHECK(klass->GetIFields() == NULL);
CheckProxyConstructor(klass->GetDirectMethod(0));
for (size_t i = 0; i < num_virtual_methods; ++i) {
- SirtRef<AbstractMethod> prototype(self, methods->Get(i));
+ SirtRef<mirror::AbstractMethod> prototype(self, methods->Get(i));
CheckProxyMethod(klass->GetVirtualMethod(i), prototype);
}
@@ -2445,27 +2481,29 @@
name->ToModifiedUtf8().c_str()));
CHECK_EQ(PrettyField(klass->GetStaticField(1)), throws_field_name);
- SynthesizedProxyClass* synth_proxy_class = down_cast<SynthesizedProxyClass*>(klass.get());
+ mirror::SynthesizedProxyClass* synth_proxy_class =
+ down_cast<mirror::SynthesizedProxyClass*>(klass.get());
CHECK_EQ(synth_proxy_class->GetInterfaces(), interfaces);
CHECK_EQ(synth_proxy_class->GetThrows(), throws);
}
return klass.get();
}
-std::string ClassLinker::GetDescriptorForProxy(const Class* proxy_class) {
+std::string ClassLinker::GetDescriptorForProxy(const mirror::Class* proxy_class) {
DCHECK(proxy_class->IsProxyClass());
- String* name = proxy_class->GetName();
+ mirror::String* name = proxy_class->GetName();
DCHECK(name != NULL);
return DotToDescriptor(name->ToModifiedUtf8().c_str());
}
-AbstractMethod* ClassLinker::FindMethodForProxy(const Class* proxy_class, const AbstractMethod* proxy_method) {
+mirror::AbstractMethod* ClassLinker::FindMethodForProxy(const mirror::Class* proxy_class,
+ const mirror::AbstractMethod* proxy_method) {
DCHECK(proxy_class->IsProxyClass());
DCHECK(proxy_method->IsProxyMethod());
// Locate the dex cache of the original interface/Object
- DexCache* dex_cache = NULL;
+ mirror::DexCache* dex_cache = NULL;
{
- ObjectArray<Class>* resolved_types = proxy_method->GetDexCacheResolvedTypes();
+ mirror::ObjectArray<mirror::Class>* resolved_types = proxy_method->GetDexCacheResolvedTypes();
MutexLock mu(Thread::Current(), dex_lock_);
for (size_t i = 0; i != dex_caches_.size(); ++i) {
if (dex_caches_[i]->GetResolvedTypes() == resolved_types) {
@@ -2476,27 +2514,31 @@
}
CHECK(dex_cache != NULL);
uint32_t method_idx = proxy_method->GetDexMethodIndex();
- AbstractMethod* resolved_method = dex_cache->GetResolvedMethod(method_idx);
+ mirror::AbstractMethod* resolved_method = dex_cache->GetResolvedMethod(method_idx);
CHECK(resolved_method != NULL);
return resolved_method;
}
-AbstractMethod* ClassLinker::CreateProxyConstructor(Thread* self, SirtRef<Class>& klass, Class* proxy_class) {
+mirror::AbstractMethod* ClassLinker::CreateProxyConstructor(Thread* self,
+ SirtRef<mirror::Class>& klass,
+ mirror::Class* proxy_class) {
// Create constructor for Proxy that must initialize h
- ObjectArray<AbstractMethod>* proxy_direct_methods = proxy_class->GetDirectMethods();
+ mirror::ObjectArray<mirror::AbstractMethod>* proxy_direct_methods =
+ proxy_class->GetDirectMethods();
CHECK_EQ(proxy_direct_methods->GetLength(), 15);
- AbstractMethod* proxy_constructor = proxy_direct_methods->Get(2);
+ mirror::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(self));
+ mirror::AbstractMethod* constructor =
+ down_cast<mirror::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());
return constructor;
}
-static void CheckProxyConstructor(AbstractMethod* constructor)
+static void CheckProxyConstructor(mirror::AbstractMethod* constructor)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK(constructor->IsConstructor());
MethodHelper mh(constructor);
@@ -2505,15 +2547,15 @@
DCHECK(constructor->IsPublic());
}
-AbstractMethod* ClassLinker::CreateProxyMethod(Thread* self, SirtRef<Class>& klass,
- SirtRef<AbstractMethod>& prototype) {
+mirror::AbstractMethod* ClassLinker::CreateProxyMethod(Thread* self, SirtRef<mirror::Class>& klass,
+ SirtRef<mirror::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(self));
+ mirror::AbstractMethod* method = down_cast<mirror::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
@@ -2522,7 +2564,8 @@
// At runtime the method looks like a reference and argument saving method, clone the code
// related parameters from this method.
- AbstractMethod* refs_and_args = Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs);
+ mirror::AbstractMethod* refs_and_args =
+ Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs);
method->SetCoreSpillMask(refs_and_args->GetCoreSpillMask());
method->SetFpSpillMask(refs_and_args->GetFpSpillMask());
method->SetFrameSizeInBytes(refs_and_args->GetFrameSizeInBytes());
@@ -2536,7 +2579,8 @@
return method;
}
-static void CheckProxyMethod(AbstractMethod* method, SirtRef<AbstractMethod>& prototype)
+static void CheckProxyMethod(mirror::AbstractMethod* method,
+ SirtRef<mirror::AbstractMethod>& prototype)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Basic sanity
CHECK(!prototype->IsFinal());
@@ -2560,18 +2604,18 @@
CHECK_EQ(mh.GetReturnType(), mh2.GetReturnType());
}
-bool ClassLinker::InitializeClass(Class* klass, bool can_run_clinit, bool can_init_statics) {
+bool ClassLinker::InitializeClass(mirror::Class* klass, bool can_run_clinit, bool can_init_statics) {
CHECK(klass->IsResolved() || klass->IsErroneous())
<< PrettyClass(klass) << ": state=" << klass->GetStatus();
Thread* self = Thread::Current();
- AbstractMethod* clinit = NULL;
+ mirror::AbstractMethod* clinit = NULL;
{
// see JLS 3rd edition, 12.4.2 "Detailed Initialization Procedure" for the locking protocol
ObjectLock lock(self, klass);
- if (klass->GetStatus() == Class::kStatusInitialized) {
+ if (klass->GetStatus() == mirror::Class::kStatusInitialized) {
return true;
}
@@ -2580,11 +2624,11 @@
return false;
}
- if (klass->GetStatus() == Class::kStatusResolved ||
- klass->GetStatus() == Class::kStatusRetryVerificationAtRuntime) {
+ if (klass->GetStatus() == mirror::Class::kStatusResolved ||
+ klass->GetStatus() == mirror::Class::kStatusRetryVerificationAtRuntime) {
VerifyClass(klass);
- if (klass->GetStatus() != Class::kStatusVerified) {
- if (klass->GetStatus() == Class::kStatusError) {
+ if (klass->GetStatus() != mirror::Class::kStatusVerified) {
+ if (klass->GetStatus() == mirror::Class::kStatusError) {
CHECK(self->IsExceptionPending());
}
return false;
@@ -2606,7 +2650,7 @@
// to initializing and we need to wait. Either way, this
// invocation of InitializeClass will not be responsible for
// running <clinit> and will return.
- if (klass->GetStatus() == Class::kStatusInitializing) {
+ if (klass->GetStatus() == mirror::Class::kStatusInitializing) {
// We caught somebody else in the act; was it us?
if (klass->GetClinitThreadId() == self->GetTid()) {
// Yes. That's fine. Return so we can continue initializing.
@@ -2617,15 +2661,15 @@
}
if (!ValidateSuperClassDescriptors(klass)) {
- klass->SetStatus(Class::kStatusError);
+ klass->SetStatus(mirror::Class::kStatusError);
lock.NotifyAll();
return false;
}
- DCHECK_EQ(klass->GetStatus(), Class::kStatusVerified) << PrettyClass(klass);
+ DCHECK_EQ(klass->GetStatus(), mirror::Class::kStatusVerified) << PrettyClass(klass);
klass->SetClinitThreadId(self->GetTid());
- klass->SetStatus(Class::kStatusInitializing);
+ klass->SetStatus(mirror::Class::kStatusInitializing);
}
uint64_t t0 = NanoTime();
@@ -2665,7 +2709,7 @@
if (self->IsExceptionPending()) {
WrapExceptionInInitializer();
- klass->SetStatus(Class::kStatusError);
+ klass->SetStatus(mirror::Class::kStatusError);
success = false;
} else {
RuntimeStats* global_stats = Runtime::Current()->GetStats();
@@ -2677,10 +2721,10 @@
// Set the class as initialized except if we can't initialize static fields and static field
// initialization is necessary.
if (!can_init_statics && has_static_field_initializers) {
- klass->SetStatus(Class::kStatusVerified); // Don't leave class in initializing state.
+ klass->SetStatus(mirror::Class::kStatusVerified); // Don't leave class in initializing state.
success = false;
} else {
- klass->SetStatus(Class::kStatusInitialized);
+ klass->SetStatus(mirror::Class::kStatusInitialized);
}
if (VLOG_IS_ON(class_linker)) {
ClassHelper kh(klass);
@@ -2692,7 +2736,7 @@
return success;
}
-bool ClassLinker::WaitForInitializeClass(Class* klass, Thread* self, ObjectLock& lock)
+bool ClassLinker::WaitForInitializeClass(mirror::Class* klass, Thread* self, ObjectLock& lock)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
while (true) {
self->AssertNoPendingException();
@@ -2703,14 +2747,14 @@
// "interruptShouldThrow" was set), bail out.
if (self->IsExceptionPending()) {
WrapExceptionInInitializer();
- klass->SetStatus(Class::kStatusError);
+ klass->SetStatus(mirror::Class::kStatusError);
return false;
}
// Spurious wakeup? Go back to waiting.
- if (klass->GetStatus() == Class::kStatusInitializing) {
+ if (klass->GetStatus() == mirror::Class::kStatusInitializing) {
continue;
}
- if (klass->GetStatus() == Class::kStatusVerified && Runtime::Current()->IsCompiler()) {
+ if (klass->GetStatus() == mirror::Class::kStatusVerified && Runtime::Current()->IsCompiler()) {
// Compile time initialization failed.
return false;
}
@@ -2729,16 +2773,16 @@
LOG(FATAL) << "Not Reached" << PrettyClass(klass);
}
-bool ClassLinker::ValidateSuperClassDescriptors(const Class* klass) {
+bool ClassLinker::ValidateSuperClassDescriptors(const mirror::Class* klass) {
if (klass->IsInterface()) {
return true;
}
// begin with the methods local to the superclass
if (klass->HasSuperClass() &&
klass->GetClassLoader() != klass->GetSuperClass()->GetClassLoader()) {
- const Class* super = klass->GetSuperClass();
+ const mirror::Class* super = klass->GetSuperClass();
for (int i = super->GetVTable()->GetLength() - 1; i >= 0; --i) {
- const AbstractMethod* method = klass->GetVTable()->Get(i);
+ const mirror::AbstractMethod* method = klass->GetVTable()->Get(i);
if (method != super->GetVTable()->Get(i) &&
!IsSameMethodSignatureInDifferentClassContexts(method, super, klass)) {
ThrowLinkageError("Class %s method %s resolves differently in superclass %s",
@@ -2748,12 +2792,12 @@
}
}
}
- IfTable* iftable = klass->GetIfTable();
+ mirror::IfTable* iftable = klass->GetIfTable();
for (int32_t i = 0; i < klass->GetIfTableCount(); ++i) {
- Class* interface = iftable->GetInterface(i);
+ mirror::Class* interface = iftable->GetInterface(i);
if (klass->GetClassLoader() != interface->GetClassLoader()) {
for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
- const AbstractMethod* method = iftable->GetMethodArray(i)->Get(j);
+ const mirror::AbstractMethod* method = iftable->GetMethodArray(i)->Get(j);
if (!IsSameMethodSignatureInDifferentClassContexts(method, interface,
method->GetDeclaringClass())) {
ThrowLinkageError("Class %s method %s resolves differently in interface %s",
@@ -2770,9 +2814,9 @@
// Returns true if classes referenced by the signature of the method are the
// same classes in klass1 as they are in klass2.
-bool ClassLinker::IsSameMethodSignatureInDifferentClassContexts(const AbstractMethod* method,
- const Class* klass1,
- const Class* klass2) {
+bool ClassLinker::IsSameMethodSignatureInDifferentClassContexts(const mirror::AbstractMethod* method,
+ const mirror::Class* klass1,
+ const mirror::Class* klass2) {
if (klass1 == klass2) {
return true;
}
@@ -2803,29 +2847,29 @@
// Returns true if the descriptor resolves to the same class in the context of klass1 and klass2.
bool ClassLinker::IsSameDescriptorInDifferentClassContexts(const char* descriptor,
- const Class* klass1,
- const Class* klass2) {
+ const mirror::Class* klass1,
+ const mirror::Class* klass2) {
CHECK(descriptor != NULL);
CHECK(klass1 != NULL);
CHECK(klass2 != NULL);
if (klass1 == klass2) {
return true;
}
- Class* found1 = FindClass(descriptor, klass1->GetClassLoader());
+ mirror::Class* found1 = FindClass(descriptor, klass1->GetClassLoader());
if (found1 == NULL) {
Thread::Current()->ClearException();
}
- Class* found2 = FindClass(descriptor, klass2->GetClassLoader());
+ mirror::Class* found2 = FindClass(descriptor, klass2->GetClassLoader());
if (found2 == NULL) {
Thread::Current()->ClearException();
}
return found1 == found2;
}
-bool ClassLinker::InitializeSuperClass(Class* klass, bool can_run_clinit, bool can_init_fields) {
+bool ClassLinker::InitializeSuperClass(mirror::Class* klass, bool can_run_clinit, bool can_init_fields) {
CHECK(klass != NULL);
if (!klass->IsInterface() && klass->HasSuperClass()) {
- Class* super_class = klass->GetSuperClass();
+ mirror::Class* super_class = klass->GetSuperClass();
if (!super_class->IsInitialized()) {
CHECK(!super_class->IsInterface());
// Must hold lock on object when initializing and setting status.
@@ -2835,11 +2879,11 @@
if (!super_initialized) {
if (!can_run_clinit) {
// Don't set status to error when we can't run <clinit>.
- CHECK_EQ(klass->GetStatus(), Class::kStatusInitializing) << PrettyClass(klass);
- klass->SetStatus(Class::kStatusVerified);
+ CHECK_EQ(klass->GetStatus(), mirror::Class::kStatusInitializing) << PrettyClass(klass);
+ klass->SetStatus(mirror::Class::kStatusVerified);
return false;
}
- klass->SetStatus(Class::kStatusError);
+ klass->SetStatus(mirror::Class::kStatusError);
klass->NotifyAll();
return false;
}
@@ -2848,7 +2892,7 @@
return true;
}
-bool ClassLinker::EnsureInitialized(Class* c, bool can_run_clinit, bool can_init_fields) {
+bool ClassLinker::EnsureInitialized(mirror::Class* c, bool can_run_clinit, bool can_init_fields) {
DCHECK(c != NULL);
if (c->IsInitialized()) {
return true;
@@ -2864,8 +2908,8 @@
}
void ClassLinker::ConstructFieldMap(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
- Class* c, SafeMap<uint32_t, Field*>& field_map) {
- ClassLoader* cl = c->GetClassLoader();
+ mirror::Class* c, SafeMap<uint32_t, mirror::Field*>& field_map) {
+ mirror::ClassLoader* cl = c->GetClassLoader();
const byte* class_data = dex_file.GetClassData(dex_class_def);
ClassDataItemIterator it(dex_file, class_data);
for (size_t i = 0; it.HasNextStaticField(); i++, it.Next()) {
@@ -2873,12 +2917,12 @@
}
}
-bool ClassLinker::InitializeStaticFields(Class* klass) {
+bool ClassLinker::InitializeStaticFields(mirror::Class* klass) {
size_t num_static_fields = klass->NumStaticFields();
if (num_static_fields == 0) {
return false;
}
- DexCache* dex_cache = klass->GetDexCache();
+ mirror::DexCache* dex_cache = klass->GetDexCache();
// TODO: this seems like the wrong check. do we really want !IsPrimitive && !IsArray?
if (dex_cache == NULL) {
return false;
@@ -2892,7 +2936,7 @@
if (it.HasNext()) {
// We reordered the fields, so we need to be able to map the field indexes to the right fields.
- SafeMap<uint32_t, Field*> field_map;
+ SafeMap<uint32_t, mirror::Field*> field_map;
ConstructFieldMap(dex_file, *dex_class_def, klass, field_map);
for (size_t i = 0; it.HasNext(); i++, it.Next()) {
it.ReadValueToField(field_map.Get(i));
@@ -2902,8 +2946,9 @@
return false;
}
-bool ClassLinker::LinkClass(SirtRef<Class>& klass, ObjectArray<Class>* interfaces) {
- CHECK_EQ(Class::kStatusLoaded, klass->GetStatus());
+bool ClassLinker::LinkClass(SirtRef<mirror::Class>& klass,
+ mirror::ObjectArray<mirror::Class>* interfaces) {
+ CHECK_EQ(mirror::Class::kStatusLoaded, klass->GetStatus());
if (!LinkSuperClass(klass)) {
return false;
}
@@ -2918,19 +2963,19 @@
}
CreateReferenceInstanceOffsets(klass);
CreateReferenceStaticOffsets(klass);
- CHECK_EQ(Class::kStatusLoaded, klass->GetStatus());
- klass->SetStatus(Class::kStatusResolved);
+ CHECK_EQ(mirror::Class::kStatusLoaded, klass->GetStatus());
+ klass->SetStatus(mirror::Class::kStatusResolved);
return true;
}
-bool ClassLinker::LoadSuperAndInterfaces(SirtRef<Class>& klass, const DexFile& dex_file) {
- CHECK_EQ(Class::kStatusIdx, klass->GetStatus());
+bool ClassLinker::LoadSuperAndInterfaces(SirtRef<mirror::Class>& klass, const DexFile& dex_file) {
+ CHECK_EQ(mirror::Class::kStatusIdx, klass->GetStatus());
StringPiece descriptor(dex_file.StringByTypeIdx(klass->GetDexTypeIndex()));
const DexFile::ClassDef* class_def = dex_file.FindClassDef(descriptor);
CHECK(class_def != NULL);
uint16_t super_class_idx = class_def->superclass_idx_;
if (super_class_idx != DexFile::kDexNoIndex16) {
- Class* super_class = ResolveType(dex_file, super_class_idx, klass.get());
+ mirror::Class* super_class = ResolveType(dex_file, super_class_idx, klass.get());
if (super_class == NULL) {
DCHECK(Thread::Current()->IsExceptionPending());
return false;
@@ -2949,7 +2994,7 @@
if (interfaces != NULL) {
for (size_t i = 0; i < interfaces->Size(); i++) {
uint16_t idx = interfaces->GetTypeItem(i).type_idx_;
- Class* interface = ResolveType(dex_file, idx, klass.get());
+ mirror::Class* interface = ResolveType(dex_file, idx, klass.get());
if (interface == NULL) {
DCHECK(Thread::Current()->IsExceptionPending());
return false;
@@ -2966,13 +3011,13 @@
}
}
// Mark the class as loaded.
- klass->SetStatus(Class::kStatusLoaded);
+ klass->SetStatus(mirror::Class::kStatusLoaded);
return true;
}
-bool ClassLinker::LinkSuperClass(SirtRef<Class>& klass) {
+bool ClassLinker::LinkSuperClass(SirtRef<mirror::Class>& klass) {
CHECK(!klass->IsPrimitive());
- Class* super = klass->GetSuperClass();
+ mirror::Class* super = klass->GetSuperClass();
if (klass.get() == GetClassRoot(kJavaLangObject)) {
if (super != NULL) {
Thread::Current()->ThrowNewExceptionF("Ljava/lang/ClassFormatError;",
@@ -3031,7 +3076,8 @@
}
// Populate the class vtable and itable. Compute return type indices.
-bool ClassLinker::LinkMethods(SirtRef<Class>& klass, ObjectArray<Class>* interfaces) {
+bool ClassLinker::LinkMethods(SirtRef<mirror::Class>& klass,
+ mirror::ObjectArray<mirror::Class>* interfaces) {
if (klass->IsInterface()) {
// No vtable.
size_t count = klass->NumVirtualMethods();
@@ -3051,24 +3097,24 @@
return true;
}
-bool ClassLinker::LinkVirtualMethods(SirtRef<Class>& klass) {
+bool ClassLinker::LinkVirtualMethods(SirtRef<mirror::Class>& klass) {
Thread* self = Thread::Current();
if (klass->HasSuperClass()) {
uint32_t max_count = klass->NumVirtualMethods() + klass->GetSuperClass()->GetVTable()->GetLength();
size_t actual_count = klass->GetSuperClass()->GetVTable()->GetLength();
CHECK_LE(actual_count, max_count);
// TODO: do not assign to the vtable field until it is fully constructed.
- SirtRef<ObjectArray<AbstractMethod> >
+ SirtRef<mirror::ObjectArray<mirror::AbstractMethod> >
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);
for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
- AbstractMethod* local_method = klass->GetVirtualMethodDuringLinking(i);
+ mirror::AbstractMethod* local_method = klass->GetVirtualMethodDuringLinking(i);
local_mh.ChangeMethod(local_method);
size_t j = 0;
for (; j < actual_count; ++j) {
- AbstractMethod* super_method = vtable->Get(j);
+ mirror::AbstractMethod* super_method = vtable->Get(j);
super_mh.ChangeMethod(super_method);
if (local_mh.HasSameNameAndSignature(&super_mh)) {
if (klass->CanAccessMember(super_method->GetDeclaringClass(), super_method->GetAccessFlags())) {
@@ -3112,10 +3158,10 @@
ThrowClassFormatError("Too many methods: %d", num_virtual_methods);
return false;
}
- SirtRef<ObjectArray<AbstractMethod> >
+ SirtRef<mirror::ObjectArray<mirror::AbstractMethod> >
vtable(self, AllocMethodArray(self, num_virtual_methods));
for (size_t i = 0; i < num_virtual_methods; ++i) {
- AbstractMethod* virtual_method = klass->GetVirtualMethodDuringLinking(i);
+ mirror::AbstractMethod* virtual_method = klass->GetVirtualMethodDuringLinking(i);
vtable->Set(i, virtual_method);
virtual_method->SetMethodIndex(i & 0xFFFF);
}
@@ -3124,7 +3170,8 @@
return true;
}
-bool ClassLinker::LinkInterfaceMethods(SirtRef<Class>& klass, ObjectArray<Class>* interfaces) {
+bool ClassLinker::LinkInterfaceMethods(SirtRef<mirror::Class>& klass,
+ mirror::ObjectArray<mirror::Class>* interfaces) {
size_t super_ifcount;
if (klass->HasSuperClass()) {
super_ifcount = klass->GetSuperClass()->GetIfTableCount();
@@ -3136,7 +3183,7 @@
uint32_t num_interfaces = interfaces == NULL ? kh.NumDirectInterfaces() : interfaces->GetLength();
ifcount += num_interfaces;
for (size_t i = 0; i < num_interfaces; i++) {
- Class* interface = interfaces == NULL ? kh.GetDirectInterface(i) : interfaces->Get(i);
+ mirror::Class* interface = interfaces == NULL ? kh.GetDirectInterface(i) : interfaces->Get(i);
ifcount += interface->GetIfTableCount();
}
if (ifcount == 0) {
@@ -3148,7 +3195,7 @@
if (ifcount == super_ifcount) {
// Class implements same interfaces as parent, are any of these not marker interfaces?
bool has_non_marker_interface = false;
- IfTable* super_iftable = klass->GetSuperClass()->GetIfTable();
+ mirror::IfTable* super_iftable = klass->GetSuperClass()->GetIfTable();
for (size_t i = 0; i < ifcount; ++i) {
if (super_iftable->GetMethodArrayCount(i) > 0) {
has_non_marker_interface = true;
@@ -3162,18 +3209,18 @@
}
}
Thread* self = Thread::Current();
- SirtRef<IfTable> iftable(self, AllocIfTable(self, ifcount));
+ SirtRef<mirror::IfTable> iftable(self, AllocIfTable(self, ifcount));
if (super_ifcount != 0) {
- IfTable* super_iftable = klass->GetSuperClass()->GetIfTable();
+ mirror::IfTable* super_iftable = klass->GetSuperClass()->GetIfTable();
for (size_t i = 0; i < super_ifcount; i++) {
- Class* super_interface = super_iftable->GetInterface(i);
+ mirror::Class* super_interface = super_iftable->GetInterface(i);
iftable->SetInterface(i, super_interface);
}
}
// Flatten the interface inheritance hierarchy.
size_t idx = super_ifcount;
for (size_t i = 0; i < num_interfaces; i++) {
- Class* interface = interfaces == NULL ? kh.GetDirectInterface(i) : interfaces->Get(i);
+ mirror::Class* interface = interfaces == NULL ? kh.GetDirectInterface(i) : interfaces->Get(i);
DCHECK(interface != NULL);
if (!interface->IsInterface()) {
ClassHelper ih(interface);
@@ -3186,7 +3233,7 @@
// Check if interface is already in iftable
bool duplicate = false;
for (size_t j = 0; j < idx; j++) {
- Class* existing_interface = iftable->GetInterface(j);
+ mirror::Class* existing_interface = iftable->GetInterface(j);
if (existing_interface == interface) {
duplicate = true;
break;
@@ -3197,10 +3244,10 @@
iftable->SetInterface(idx++, interface);
// Add this interface's non-duplicate super-interfaces.
for (int32_t j = 0; j < interface->GetIfTableCount(); j++) {
- Class* super_interface = interface->GetIfTable()->GetInterface(j);
+ mirror::Class* super_interface = interface->GetIfTable()->GetInterface(j);
bool super_duplicate = false;
for (size_t k = 0; k < idx; k++) {
- Class* existing_interface = iftable->GetInterface(k);
+ mirror::Class* existing_interface = iftable->GetInterface(k);
if (existing_interface == super_interface) {
super_duplicate = true;
break;
@@ -3214,7 +3261,7 @@
}
// Shrink iftable in case duplicates were found
if (idx < ifcount) {
- iftable.reset(down_cast<IfTable*>(iftable->CopyOf(self, idx * IfTable::kMax)));
+ iftable.reset(down_cast<mirror::IfTable*>(iftable->CopyOf(self, idx * mirror::IfTable::kMax)));
ifcount = idx;
} else {
CHECK_EQ(idx, ifcount);
@@ -3225,18 +3272,19 @@
if (klass->IsInterface()) {
return true;
}
- std::vector<AbstractMethod*> miranda_list;
+ std::vector<mirror::AbstractMethod*> miranda_list;
MethodHelper vtable_mh(NULL, this);
MethodHelper interface_mh(NULL, this);
for (size_t i = 0; i < ifcount; ++i) {
- Class* interface = iftable->GetInterface(i);
+ mirror::Class* interface = iftable->GetInterface(i);
size_t num_methods = interface->NumVirtualMethods();
if (num_methods > 0) {
- ObjectArray<AbstractMethod>* method_array = AllocMethodArray(self, num_methods);
+ mirror::ObjectArray<mirror::AbstractMethod>* method_array =
+ AllocMethodArray(self, num_methods);
iftable->SetMethodArray(i, method_array);
- ObjectArray<AbstractMethod>* vtable = klass->GetVTableDuringLinking();
+ mirror::ObjectArray<mirror::AbstractMethod>* vtable = klass->GetVTableDuringLinking();
for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
- AbstractMethod* interface_method = interface->GetVirtualMethod(j);
+ mirror::AbstractMethod* interface_method = interface->GetVirtualMethod(j);
interface_mh.ChangeMethod(interface_method);
int32_t k;
// For each method listed in the interface's method list, find the
@@ -3248,7 +3296,7 @@
// those don't end up in the virtual method table, so it shouldn't
// matter which direction we go. We walk it backward anyway.)
for (k = vtable->GetLength() - 1; k >= 0; --k) {
- AbstractMethod* vtable_method = vtable->Get(k);
+ mirror::AbstractMethod* vtable_method = vtable->Get(k);
vtable_mh.ChangeMethod(vtable_method);
if (interface_mh.HasSameNameAndSignature(&vtable_mh)) {
if (!vtable_method->IsPublic()) {
@@ -3262,9 +3310,9 @@
}
}
if (k < 0) {
- SirtRef<AbstractMethod> miranda_method(self, NULL);
+ SirtRef<mirror::AbstractMethod> miranda_method(self, NULL);
for (size_t mir = 0; mir < miranda_list.size(); mir++) {
- AbstractMethod* mir_method = miranda_list[mir];
+ mirror::AbstractMethod* mir_method = miranda_list[mir];
vtable_mh.ChangeMethod(mir_method);
if (interface_mh.HasSameNameAndSignature(&vtable_mh)) {
miranda_method.reset(miranda_list[mir]);
@@ -3273,7 +3321,7 @@
}
if (miranda_method.get() == NULL) {
// point the interface table at a phantom slot
- miranda_method.reset(down_cast<AbstractMethod*>(interface_method->Clone(self)));
+ miranda_method.reset(down_cast<mirror::AbstractMethod*>(interface_method->Clone(self)));
miranda_list.push_back(miranda_method.get());
}
method_array->Set(j, miranda_method.get());
@@ -3288,13 +3336,14 @@
? AllocMethodArray(self, new_method_count)
: klass->GetVirtualMethods()->CopyOf(self, new_method_count));
- SirtRef<ObjectArray<AbstractMethod> > vtable(self, klass->GetVTableDuringLinking());
+ SirtRef<mirror::ObjectArray<mirror::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(self, new_vtable_count));
for (size_t i = 0; i < miranda_list.size(); ++i) {
- AbstractMethod* method = miranda_list[i];
+ mirror::AbstractMethod* method = miranda_list[i];
// Leave the declaring class alone as type indices are relative to it
method->SetAccessFlags(method->GetAccessFlags() | kAccMiranda);
method->SetMethodIndex(0xFFFF & (old_vtable_count + i));
@@ -3305,7 +3354,7 @@
klass->SetVTable(vtable.get());
}
- ObjectArray<AbstractMethod>* vtable = klass->GetVTableDuringLinking();
+ mirror::ObjectArray<mirror::AbstractMethod>* vtable = klass->GetVTableDuringLinking();
for (int i = 0; i < vtable->GetLength(); ++i) {
CHECK(vtable->Get(i) != NULL);
}
@@ -3315,12 +3364,12 @@
return true;
}
-bool ClassLinker::LinkInstanceFields(SirtRef<Class>& klass) {
+bool ClassLinker::LinkInstanceFields(SirtRef<mirror::Class>& klass) {
CHECK(klass.get() != NULL);
return LinkFields(klass, false);
}
-bool ClassLinker::LinkStaticFields(SirtRef<Class>& klass) {
+bool ClassLinker::LinkStaticFields(SirtRef<mirror::Class>& klass) {
CHECK(klass.get() != NULL);
size_t allocated_class_size = klass->GetClassSize();
bool success = LinkFields(klass, true);
@@ -3333,7 +3382,8 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: fh_(fh) {}
// No thread safety analysis as will be called from STL. Checked lock held in constructor.
- bool operator()(const Field* field1, const Field* field2) NO_THREAD_SAFETY_ANALYSIS {
+ bool operator()(const mirror::Field* field1, const mirror::Field* field2)
+ NO_THREAD_SAFETY_ANALYSIS {
// First come reference fields, then 64-bit, and finally 32-bit
fh_->ChangeField(field1);
Primitive::Type type1 = fh_->GetTypeAsPrimitiveType();
@@ -3360,11 +3410,11 @@
FieldHelper* fh_;
};
-bool ClassLinker::LinkFields(SirtRef<Class>& klass, bool is_static) {
+bool ClassLinker::LinkFields(SirtRef<mirror::Class>& klass, bool is_static) {
size_t num_fields =
is_static ? klass->NumStaticFields() : klass->NumInstanceFields();
- ObjectArray<Field>* fields =
+ mirror::ObjectArray<mirror::Field>* fields =
is_static ? klass->GetSFields() : klass->GetIFields();
// Initialize size and field_offset
@@ -3372,9 +3422,9 @@
MemberOffset field_offset(0);
if (is_static) {
size = klass->GetClassSize();
- field_offset = Class::FieldsOffset();
+ field_offset = mirror::Class::FieldsOffset();
} else {
- Class* super_class = klass->GetSuperClass();
+ mirror::Class* super_class = klass->GetSuperClass();
if (super_class != NULL) {
CHECK(super_class->IsResolved());
field_offset = MemberOffset(super_class->GetObjectSize());
@@ -3386,7 +3436,7 @@
// we want a relatively stable order so that adding new fields
// minimizes disruption of C++ version such as Class and Method.
- std::deque<Field*> grouped_and_sorted_fields;
+ std::deque<mirror::Field*> grouped_and_sorted_fields;
for (size_t i = 0; i < num_fields; i++) {
grouped_and_sorted_fields.push_back(fields->Get(i));
}
@@ -3399,7 +3449,7 @@
size_t current_field = 0;
size_t num_reference_fields = 0;
for (; current_field < num_fields; current_field++) {
- Field* field = grouped_and_sorted_fields.front();
+ mirror::Field* field = grouped_and_sorted_fields.front();
fh.ChangeField(field);
Primitive::Type type = fh.GetTypeAsPrimitiveType();
bool isPrimitive = type != Primitive::kPrimNot;
@@ -3418,7 +3468,7 @@
// into place. If we can't find one, we'll have to pad it.
if (current_field != num_fields && !IsAligned<8>(field_offset.Uint32Value())) {
for (size_t i = 0; i < grouped_and_sorted_fields.size(); i++) {
- Field* field = grouped_and_sorted_fields[i];
+ mirror::Field* field = grouped_and_sorted_fields[i];
fh.ChangeField(field);
Primitive::Type type = fh.GetTypeAsPrimitiveType();
CHECK(type != Primitive::kPrimNot); // should only be working on primitive types
@@ -3439,7 +3489,7 @@
// finish assigning field offsets to all fields.
DCHECK(current_field == num_fields || IsAligned<8>(field_offset.Uint32Value()));
while (!grouped_and_sorted_fields.empty()) {
- Field* field = grouped_and_sorted_fields.front();
+ mirror::Field* field = grouped_and_sorted_fields.front();
grouped_and_sorted_fields.pop_front();
fh.ChangeField(field);
Primitive::Type type = fh.GetTypeAsPrimitiveType();
@@ -3469,12 +3519,13 @@
// non-reference fields, and all double-wide fields are aligned.
bool seen_non_ref = false;
for (size_t i = 0; i < num_fields; i++) {
- Field* field = fields->Get(i);
+ mirror::Field* field = fields->Get(i);
if (false) { // enable to debug field layout
LOG(INFO) << "LinkFields: " << (is_static ? "static" : "instance")
<< " class=" << PrettyClass(klass.get())
<< " field=" << PrettyField(field)
- << " offset=" << field->GetField32(MemberOffset(Field::OffsetOffset()), false);
+ << " offset=" << field->GetField32(MemberOffset(mirror::Field::OffsetOffset()),
+ false);
}
fh.ChangeField(field);
Primitive::Type type = fh.GetTypeAsPrimitiveType();
@@ -3512,9 +3563,9 @@
// Set the bitmap of reference offsets, refOffsets, from the ifields
// list.
-void ClassLinker::CreateReferenceInstanceOffsets(SirtRef<Class>& klass) {
+void ClassLinker::CreateReferenceInstanceOffsets(SirtRef<mirror::Class>& klass) {
uint32_t reference_offsets = 0;
- Class* super_class = klass->GetSuperClass();
+ mirror::Class* super_class = klass->GetSuperClass();
if (super_class != NULL) {
reference_offsets = super_class->GetReferenceInstanceOffsets();
// If our superclass overflowed, we don't stand a chance.
@@ -3526,23 +3577,23 @@
CreateReferenceOffsets(klass, false, reference_offsets);
}
-void ClassLinker::CreateReferenceStaticOffsets(SirtRef<Class>& klass) {
+void ClassLinker::CreateReferenceStaticOffsets(SirtRef<mirror::Class>& klass) {
CreateReferenceOffsets(klass, true, 0);
}
-void ClassLinker::CreateReferenceOffsets(SirtRef<Class>& klass, bool is_static,
+void ClassLinker::CreateReferenceOffsets(SirtRef<mirror::Class>& klass, bool is_static,
uint32_t reference_offsets) {
size_t num_reference_fields =
is_static ? klass->NumReferenceStaticFieldsDuringLinking()
: klass->NumReferenceInstanceFieldsDuringLinking();
- const ObjectArray<Field>* fields =
+ const mirror::ObjectArray<mirror::Field>* fields =
is_static ? klass->GetSFields() : klass->GetIFields();
// All of the fields that contain object references are guaranteed
// to be at the beginning of the fields list.
for (size_t i = 0; i < num_reference_fields; ++i) {
// Note that byte_offset is the offset from the beginning of
// object, not the offset into instance data
- const Field* field = fields->Get(i);
+ const mirror::Field* field = fields->Get(i);
MemberOffset byte_offset = field->GetOffsetDuringLinking();
CHECK_EQ(byte_offset.Uint32Value() & (CLASS_OFFSET_ALIGNMENT - 1), 0U);
if (CLASS_CAN_ENCODE_OFFSET(byte_offset.Uint32Value())) {
@@ -3562,27 +3613,27 @@
}
}
-String* ClassLinker::ResolveString(const DexFile& dex_file,
- uint32_t string_idx, DexCache* dex_cache) {
+mirror::String* ClassLinker::ResolveString(const DexFile& dex_file,
+ uint32_t string_idx, mirror::DexCache* dex_cache) {
DCHECK(dex_cache != NULL);
- String* resolved = dex_cache->GetResolvedString(string_idx);
+ mirror::String* resolved = dex_cache->GetResolvedString(string_idx);
if (resolved != NULL) {
return resolved;
}
const DexFile::StringId& string_id = dex_file.GetStringId(string_idx);
int32_t utf16_length = dex_file.GetStringLength(string_id);
const char* utf8_data = dex_file.GetStringData(string_id);
- String* string = intern_table_->InternStrong(utf16_length, utf8_data);
+ mirror::String* string = intern_table_->InternStrong(utf16_length, utf8_data);
dex_cache->SetResolvedString(string_idx, string);
return string;
}
-Class* ClassLinker::ResolveType(const DexFile& dex_file,
- uint16_t type_idx,
- DexCache* dex_cache,
- ClassLoader* class_loader) {
+mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file,
+ uint16_t type_idx,
+ mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader) {
DCHECK(dex_cache != NULL);
- Class* resolved = dex_cache->GetResolvedType(type_idx);
+ mirror::Class* resolved = dex_cache->GetResolvedType(type_idx);
if (resolved == NULL) {
const char* descriptor = dex_file.StringByTypeIdx(type_idx);
resolved = FindClass(descriptor, class_loader);
@@ -3604,21 +3655,21 @@
return resolved;
}
-AbstractMethod* ClassLinker::ResolveMethod(const DexFile& dex_file,
- uint32_t method_idx,
- DexCache* dex_cache,
- ClassLoader* class_loader,
- const AbstractMethod* referrer,
- InvokeType type) {
+mirror::AbstractMethod* ClassLinker::ResolveMethod(const DexFile& dex_file,
+ uint32_t method_idx,
+ mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader,
+ const mirror::AbstractMethod* referrer,
+ InvokeType type) {
DCHECK(dex_cache != NULL);
// Check for hit in the dex cache.
- AbstractMethod* resolved = dex_cache->GetResolvedMethod(method_idx);
+ mirror::AbstractMethod* resolved = dex_cache->GetResolvedMethod(method_idx);
if (resolved != NULL) {
return resolved;
}
// Fail, get the declaring class.
const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
- Class* klass = ResolveType(dex_file, method_id.class_idx_, dex_cache, class_loader);
+ mirror::Class* klass = ResolveType(dex_file, method_id.class_idx_, dex_cache, class_loader);
if (klass == NULL) {
DCHECK(Thread::Current()->IsExceptionPending());
return NULL;
@@ -3689,8 +3740,8 @@
// If we found something, check that it can be accessed by the referrer.
if (resolved != NULL && referrer != NULL) {
- Class* methods_class = resolved->GetDeclaringClass();
- Class* referring_class = referrer->GetDeclaringClass();
+ mirror::Class* methods_class = resolved->GetDeclaringClass();
+ mirror::Class* referring_class = referrer->GetDeclaringClass();
if (!referring_class->CanAccess(methods_class)) {
ThrowIllegalAccessErrorClassForMethodDispatch(referring_class, methods_class,
referrer, resolved, type);
@@ -3751,18 +3802,18 @@
}
}
-Field* ClassLinker::ResolveField(const DexFile& dex_file,
- uint32_t field_idx,
- DexCache* dex_cache,
- ClassLoader* class_loader,
- bool is_static) {
+mirror::Field* ClassLinker::ResolveField(const DexFile& dex_file,
+ uint32_t field_idx,
+ mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader,
+ bool is_static) {
DCHECK(dex_cache != NULL);
- Field* resolved = dex_cache->GetResolvedField(field_idx);
+ mirror::Field* resolved = dex_cache->GetResolvedField(field_idx);
if (resolved != NULL) {
return resolved;
}
const DexFile::FieldId& field_id = dex_file.GetFieldId(field_idx);
- Class* klass = ResolveType(dex_file, field_id.class_idx_, dex_cache, class_loader);
+ mirror::Class* klass = ResolveType(dex_file, field_id.class_idx_, dex_cache, class_loader);
if (klass == NULL) {
DCHECK(Thread::Current()->IsExceptionPending());
return NULL;
@@ -3791,17 +3842,17 @@
return resolved;
}
-Field* ClassLinker::ResolveFieldJLS(const DexFile& dex_file,
- uint32_t field_idx,
- DexCache* dex_cache,
- ClassLoader* class_loader) {
+mirror::Field* ClassLinker::ResolveFieldJLS(const DexFile& dex_file,
+ uint32_t field_idx,
+ mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader) {
DCHECK(dex_cache != NULL);
- Field* resolved = dex_cache->GetResolvedField(field_idx);
+ mirror::Field* resolved = dex_cache->GetResolvedField(field_idx);
if (resolved != NULL) {
return resolved;
}
const DexFile::FieldId& field_id = dex_file.GetFieldId(field_idx);
- Class* klass = ResolveType(dex_file, field_id.class_idx_, dex_cache, class_loader);
+ mirror::Class* klass = ResolveType(dex_file, field_id.class_idx_, dex_cache, class_loader);
if (klass == NULL) {
DCHECK(Thread::Current()->IsExceptionPending());
return NULL;
@@ -3818,9 +3869,10 @@
return resolved;
}
-const char* ClassLinker::MethodShorty(uint32_t method_idx, AbstractMethod* referrer, uint32_t* length) {
- Class* declaring_class = referrer->GetDeclaringClass();
- DexCache* dex_cache = declaring_class->GetDexCache();
+const char* ClassLinker::MethodShorty(uint32_t method_idx, mirror::AbstractMethod* referrer,
+ uint32_t* length) {
+ mirror::Class* declaring_class = referrer->GetDeclaringClass();
+ mirror::DexCache* dex_cache = declaring_class->GetDexCache();
const DexFile& dex_file = *dex_cache->GetDexFile();
const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx);
return dex_file.GetMethodShorty(method_id, length);
@@ -3829,7 +3881,7 @@
void ClassLinker::DumpAllClasses(int flags) const {
// TODO: at the time this was written, it wasn't safe to call PrettyField with the ClassLinker
// lock held, because it might need to resolve a field's type, which would try to take the lock.
- std::vector<Class*> all_classes;
+ std::vector<mirror::Class*> all_classes;
{
MutexLock mu(Thread::Current(), *Locks::classlinker_classes_lock_);
typedef Table::const_iterator It; // TODO: C++0x auto
@@ -3865,7 +3917,7 @@
return dex_lock_.GetExclusiveOwnerTid();
}
-void ClassLinker::SetClassRoot(ClassRoot class_root, Class* klass) {
+void ClassLinker::SetClassRoot(ClassRoot class_root, mirror::Class* klass) {
DCHECK(!init_done_);
DCHECK(klass != NULL);
diff --git a/src/class_linker.h b/src/class_linker.h
index 09a43c5..3039d55 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -23,23 +23,26 @@
#include "base/macros.h"
#include "base/mutex.h"
-#include "dex_cache.h"
#include "dex_file.h"
#include "gtest/gtest.h"
-#include "heap.h"
+#include "root_visitor.h"
#include "oat_file.h"
-#include "object.h"
-#include "safe_map.h"
namespace art {
-
+namespace mirror {
class ClassLoader;
+class DexCache;
+class DexCacheTest_Open_Test;
+class IfTable;
+template<class T> class ObjectArray;
+class StackTraceElement;
+}
class ImageSpace;
class InternTable;
class ObjectLock;
template<class T> class SirtRef;
-typedef bool (ClassVisitor)(Class* c, void* arg);
+typedef bool (ClassVisitor)(mirror::Class* c, void* arg);
class ClassLinker {
public:
@@ -56,33 +59,33 @@
// Finds a class by its descriptor, loading it if necessary.
// If class_loader is null, searches boot_class_path_.
- Class* FindClass(const char* descriptor, ClassLoader* class_loader)
+ mirror::Class* FindClass(const char* descriptor, mirror::ClassLoader* class_loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Class* FindSystemClass(const char* descriptor)
+ mirror::Class* FindSystemClass(const char* descriptor)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Define a new a class based on a ClassDef from a DexFile
- Class* DefineClass(const StringPiece& descriptor, ClassLoader* class_loader,
- const DexFile& dex_file, const DexFile::ClassDef& dex_class_def)
+ mirror::Class* DefineClass(const StringPiece& descriptor, mirror::ClassLoader* class_loader,
+ const DexFile& dex_file, const DexFile::ClassDef& dex_class_def)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Finds a class by its descriptor, returning NULL if it isn't wasn't loaded
// by the given 'class_loader'.
- Class* LookupClass(const char* descriptor, const ClassLoader* class_loader)
+ mirror::Class* LookupClass(const char* descriptor, const mirror::ClassLoader* class_loader)
LOCKS_EXCLUDED(Locks::classlinker_classes_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Finds all the classes with the given descriptor, regardless of ClassLoader.
- void LookupClasses(const char* descriptor, std::vector<Class*>& classes)
+ void LookupClasses(const char* descriptor, std::vector<mirror::Class*>& classes)
LOCKS_EXCLUDED(Locks::classlinker_classes_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Class* FindPrimitiveClass(char type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::Class* FindPrimitiveClass(char type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// General class unloading is not supported, this is used to prune
// unwanted classes during image writing.
- bool RemoveClass(const char* descriptor, const ClassLoader* class_loader)
+ bool RemoveClass(const char* descriptor, const mirror::ClassLoader* class_loader)
LOCKS_EXCLUDED(Locks::classlinker_classes_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -98,27 +101,20 @@
// Resolve a String with the given index from the DexFile, storing the
// result in the DexCache. The referrer is used to identify the
// target DexCache and ClassLoader to use for resolution.
- String* ResolveString(uint32_t string_idx, const AbstractMethod* referrer)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- String* resolved_string = referrer->GetDexCacheStrings()->Get(string_idx);
- if (UNLIKELY(resolved_string == NULL)) {
- Class* declaring_class = referrer->GetDeclaringClass();
- DexCache* dex_cache = declaring_class->GetDexCache();
- const DexFile& dex_file = *dex_cache->GetDexFile();
- resolved_string = ResolveString(dex_file, string_idx, dex_cache);
- }
- return resolved_string;
- }
+ mirror::String* ResolveString(uint32_t string_idx, const mirror::AbstractMethod* referrer)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Resolve a String with the given index from the DexFile, storing the
// result in the DexCache.
- String* ResolveString(const DexFile& dex_file, uint32_t string_idx, DexCache* dex_cache)
+ mirror::String* ResolveString(const DexFile& dex_file, uint32_t string_idx,
+ mirror::DexCache* dex_cache)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Resolve a Type with the given index from the DexFile, storing the
// result in the DexCache. The referrer is used to identity the
// target DexCache and ClassLoader to use for resolution.
- Class* ResolveType(const DexFile& dex_file, uint16_t type_idx, const Class* referrer)
+ mirror::Class* ResolveType(const DexFile& dex_file, uint16_t type_idx,
+ const mirror::Class* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return ResolveType(dex_file,
type_idx,
@@ -129,40 +125,20 @@
// Resolve a Type with the given index from the DexFile, storing the
// result in the DexCache. The referrer is used to identify the
// target DexCache and ClassLoader to use for resolution.
- Class* ResolveType(uint16_t type_idx, const AbstractMethod* referrer)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Class* resolved_type = referrer->GetDexCacheResolvedTypes()->Get(type_idx);
- if (UNLIKELY(resolved_type == NULL)) {
- Class* declaring_class = referrer->GetDeclaringClass();
- DexCache* dex_cache = declaring_class->GetDexCache();
- ClassLoader* class_loader = declaring_class->GetClassLoader();
- const DexFile& dex_file = *dex_cache->GetDexFile();
- resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader);
- }
- return resolved_type;
- }
+ mirror::Class* ResolveType(uint16_t type_idx, const mirror::AbstractMethod* referrer)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Class* ResolveType(uint16_t type_idx, const Field* referrer)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Class* declaring_class = referrer->GetDeclaringClass();
- DexCache* dex_cache = declaring_class->GetDexCache();
- Class* resolved_type = dex_cache->GetResolvedType(type_idx);
- if (UNLIKELY(resolved_type == NULL)) {
- ClassLoader* class_loader = declaring_class->GetClassLoader();
- const DexFile& dex_file = *dex_cache->GetDexFile();
- resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader);
- }
- return resolved_type;
- }
+ mirror::Class* ResolveType(uint16_t type_idx, const mirror::Field* referrer)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Resolve a type with the given ID from the DexFile, storing the
// result in DexCache. The ClassLoader is used to search for the
// type, since it may be referenced from but not contained within
// the given DexFile.
- Class* ResolveType(const DexFile& dex_file,
- uint16_t type_idx,
- DexCache* dex_cache,
- ClassLoader* class_loader)
+ mirror::Class* ResolveType(const DexFile& dex_file,
+ uint16_t type_idx,
+ mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Resolve a method with a given ID from the DexFile, storing the
@@ -170,50 +146,31 @@
// in ResolveType. What is unique is the method type argument which
// is used to determine if this method is a direct, static, or
// virtual method.
- AbstractMethod* ResolveMethod(const DexFile& dex_file,
- uint32_t method_idx,
- DexCache* dex_cache,
- ClassLoader* class_loader,
- const AbstractMethod* referrer,
- InvokeType type)
+ mirror::AbstractMethod* ResolveMethod(const DexFile& dex_file,
+ uint32_t method_idx,
+ mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader,
+ const mirror::AbstractMethod* referrer,
+ InvokeType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- AbstractMethod* ResolveMethod(uint32_t method_idx, const AbstractMethod* referrer, InvokeType type)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* resolved_method = referrer->GetDexCacheResolvedMethods()->Get(method_idx);
- if (UNLIKELY(resolved_method == NULL || resolved_method->IsRuntimeMethod())) {
- Class* declaring_class = referrer->GetDeclaringClass();
- DexCache* dex_cache = declaring_class->GetDexCache();
- ClassLoader* class_loader = declaring_class->GetClassLoader();
- const DexFile& dex_file = *dex_cache->GetDexFile();
- resolved_method = ResolveMethod(dex_file, method_idx, dex_cache, class_loader, referrer, type);
- }
- return resolved_method;
- }
+ mirror::AbstractMethod* ResolveMethod(uint32_t method_idx, const mirror::AbstractMethod* referrer,
+ InvokeType type)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Field* ResolveField(uint32_t field_idx, const AbstractMethod* referrer, bool is_static)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* resolved_field =
- referrer->GetDeclaringClass()->GetDexCache()->GetResolvedField(field_idx);
- if (UNLIKELY(resolved_field == NULL)) {
- Class* declaring_class = referrer->GetDeclaringClass();
- DexCache* dex_cache = declaring_class->GetDexCache();
- ClassLoader* class_loader = declaring_class->GetClassLoader();
- const DexFile& dex_file = *dex_cache->GetDexFile();
- resolved_field = ResolveField(dex_file, field_idx, dex_cache, class_loader, is_static);
- }
- return resolved_field;
- }
+ mirror::Field* ResolveField(uint32_t field_idx, const mirror::AbstractMethod* referrer,
+ bool is_static)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Resolve a field with a given ID from the DexFile, storing the
// result in DexCache. The ClassLinker and ClassLoader are used as
// in ResolveType. What is unique is the is_static argument which is
// used to determine if we are resolving a static or non-static
// field.
- Field* ResolveField(const DexFile& dex_file,
+ mirror::Field* ResolveField(const DexFile& dex_file,
uint32_t field_idx,
- DexCache* dex_cache,
- ClassLoader* class_loader,
+ mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader,
bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -221,20 +178,20 @@
// result in DexCache. The ClassLinker and ClassLoader are used as
// in ResolveType. No is_static argument is provided so that Java
// field resolution semantics are followed.
- Field* ResolveFieldJLS(const DexFile& dex_file,
- uint32_t field_idx,
- DexCache* dex_cache,
- ClassLoader* class_loader)
+ mirror::Field* ResolveFieldJLS(const DexFile& dex_file,
+ uint32_t field_idx,
+ mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Get shorty from method index without resolution. Used to do handlerization.
- const char* MethodShorty(uint32_t method_idx, AbstractMethod* referrer, uint32_t* length)
+ const char* MethodShorty(uint32_t method_idx, mirror::AbstractMethod* referrer, uint32_t* length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Returns true on success, false if there's an exception pending.
// can_run_clinit=false allows the compiler to attempt to init a class,
// given the restriction that no <clinit> execution is possible.
- bool EnsureInitialized(Class* c, bool can_run_clinit, bool can_init_fields)
+ bool EnsureInitialized(mirror::Class* c, bool can_run_clinit, bool can_init_fields)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Initializes classes that have instances in the image but that have
@@ -244,7 +201,7 @@
void RegisterDexFile(const DexFile& dex_file)
LOCKS_EXCLUDED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void RegisterDexFile(const DexFile& dex_file, SirtRef<DexCache>& dex_cache)
+ void RegisterDexFile(const DexFile& dex_file, SirtRef<mirror::DexCache>& dex_cache)
LOCKS_EXCLUDED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -262,15 +219,15 @@
void VisitClassesWithoutClassesLock(ClassVisitor* visitor, void* arg) const
LOCKS_EXCLUDED(Locks::classlinker_classes_lock_);
- void VisitRoots(Heap::RootVisitor* visitor, void* arg)
+ void VisitRoots(RootVisitor* visitor, void* arg)
LOCKS_EXCLUDED(Locks::classlinker_classes_lock_, dex_lock_);
- DexCache* FindDexCache(const DexFile& dex_file) const
+ mirror::DexCache* FindDexCache(const DexFile& dex_file) const
LOCKS_EXCLUDED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool IsDexFileRegistered(const DexFile& dex_file) const
LOCKS_EXCLUDED(dex_lock_);
- void FixupDexCaches(AbstractMethod* resolution_method) const
+ void FixupDexCaches(mirror::AbstractMethod* resolution_method) const
LOCKS_EXCLUDED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -310,66 +267,54 @@
// TODO: replace this with multiple methods that allocate the correct managed type.
template <class T>
- ObjectArray<T>* AllocObjectArray(Thread* self, size_t length)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ObjectArray<T>::Alloc(self, GetClassRoot(kObjectArrayClass), length);
- }
-
- ObjectArray<Class>* AllocClassArray(Thread* self, size_t length)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ObjectArray<Class>::Alloc(self, GetClassRoot(kClassArrayClass), length);
- }
-
- ObjectArray<String>* AllocStringArray(Thread* self, size_t length)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ObjectArray<String>::Alloc(self, GetClassRoot(kJavaLangStringArrayClass), length);
- }
-
- ObjectArray<AbstractMethod>* AllocAbstractMethodArray(Thread* self, size_t length)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ObjectArray<AbstractMethod>::Alloc(self,
- GetClassRoot(kJavaLangReflectAbstractMethodArrayClass), length);
- }
-
- ObjectArray<AbstractMethod>* AllocMethodArray(Thread* self, size_t length)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ObjectArray<AbstractMethod>::Alloc(self,
- GetClassRoot(kJavaLangReflectMethodArrayClass), length);
- }
-
- IfTable* AllocIfTable(Thread* self, size_t ifcount) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return down_cast<IfTable*>(
- IfTable::Alloc(self, GetClassRoot(kObjectArrayClass), ifcount * IfTable::kMax));
- }
-
- ObjectArray<Field>* AllocFieldArray(Thread* self, size_t length)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ObjectArray<Field>::Alloc(self, GetClassRoot(kJavaLangReflectFieldArrayClass), length);
- }
-
- ObjectArray<StackTraceElement>* AllocStackTraceElementArray(Thread* self, size_t length)
+ mirror::ObjectArray<T>* AllocObjectArray(Thread* self, size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void VerifyClass(Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool VerifyClassUsingOatFile(const DexFile& dex_file, Class* klass,
- Class::Status& oat_file_class_status)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void ResolveClassExceptionHandlerTypes(const DexFile& dex_file, Class* klass)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void ResolveMethodExceptionHandlerTypes(const DexFile& dex_file, AbstractMethod* klass)
+ mirror::ObjectArray<mirror::Class>* AllocClassArray(Thread* self, size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Class* CreateProxyClass(String* name, ObjectArray<Class>* interfaces, ClassLoader* loader,
- ObjectArray<AbstractMethod>* methods, ObjectArray<ObjectArray<Class> >* throws)
+ mirror::ObjectArray<mirror::String>* AllocStringArray(Thread* self, size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- std::string GetDescriptorForProxy(const Class* proxy_class)
+
+ mirror::ObjectArray<mirror::AbstractMethod>* AllocAbstractMethodArray(Thread* self, size_t length)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- AbstractMethod* FindMethodForProxy(const Class* proxy_class, const AbstractMethod* proxy_method)
+
+ mirror::ObjectArray<mirror::AbstractMethod>* AllocMethodArray(Thread* self, size_t length)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ mirror::IfTable* AllocIfTable(Thread* self, size_t ifcount)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ mirror::ObjectArray<mirror::Field>* AllocFieldArray(Thread* self, size_t length)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ mirror::ObjectArray<mirror::StackTraceElement>* AllocStackTraceElementArray(Thread* self,
+ size_t length)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void VerifyClass(mirror::Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool VerifyClassUsingOatFile(const DexFile& dex_file, mirror::Class* klass,
+ mirror::Class::Status& oat_file_class_status)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void ResolveClassExceptionHandlerTypes(const DexFile& dex_file, mirror::Class* klass)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void ResolveMethodExceptionHandlerTypes(const DexFile& dex_file, mirror::AbstractMethod* klass)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ mirror::Class* CreateProxyClass(mirror::String* name, mirror::ObjectArray<mirror::Class>* interfaces,
+ mirror::ClassLoader* loader,
+ mirror::ObjectArray<mirror::AbstractMethod>* methods,
+ mirror::ObjectArray<mirror::ObjectArray<mirror::Class> >* throws)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ std::string GetDescriptorForProxy(const mirror::Class* proxy_class)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::AbstractMethod* FindMethodForProxy(const mirror::Class* proxy_class,
+ const mirror::AbstractMethod* proxy_method)
LOCKS_EXCLUDED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Get the oat code for a method when its class isn't yet initialized
- const void* GetOatCodeFor(const AbstractMethod* method)
+ const void* GetOatCodeFor(const mirror::AbstractMethod* method)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Get the oat code for a method from a method index.
@@ -389,7 +334,7 @@
private:
explicit ClassLinker(InternTable*);
- const OatFile::OatMethod GetOatMethodFor(const AbstractMethod* method)
+ const OatFile::OatMethod GetOatMethodFor(const mirror::AbstractMethod* method)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Initialize class linker by bootstraping from dex files
@@ -401,43 +346,41 @@
OatFile* OpenOat(const ImageSpace* space)
LOCKS_EXCLUDED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static void InitFromImageCallback(Object* obj, void* arg)
+ static void InitFromImageCallback(mirror::Object* obj, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void FinishInit() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// For early bootstrapping by Init
- Class* AllocClass(Thread* self, Class* java_lang_Class, size_t class_size)
+ mirror::Class* AllocClass(Thread* self, mirror::Class* java_lang_Class, size_t class_size)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- // Alloc* convenience functions to avoid needing to pass in Class*
+ // Alloc* convenience functions to avoid needing to pass in mirror::Class*
// values that are known to the ClassLinker such as
// kObjectArrayClass and kJavaLangString etc.
- Class* AllocClass(Thread* self, size_t class_size) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- DexCache* AllocDexCache(Thread* self, const DexFile& dex_file)
+ mirror::Class* AllocClass(Thread* self, size_t class_size) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::DexCache* AllocDexCache(Thread* self, const DexFile& dex_file)
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_);
+ mirror::Field* AllocField(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::Method* AllocMethod(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::Constructor* AllocConstructor(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Class* CreatePrimitiveClass(Thread* self, Primitive::Type type)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return InitializePrimitiveClass(AllocClass(self, sizeof(Class)), type);
- }
- Class* InitializePrimitiveClass(Class* primitive_class, Primitive::Type type)
+ mirror::Class* CreatePrimitiveClass(Thread* self, Primitive::Type type)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::Class* InitializePrimitiveClass(mirror::Class* primitive_class, Primitive::Type type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Class* CreateArrayClass(const std::string& descriptor, ClassLoader* class_loader)
+ mirror::Class* CreateArrayClass(const std::string& descriptor, mirror::ClassLoader* class_loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void AppendToBootClassPath(const DexFile& dex_file)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void AppendToBootClassPath(const DexFile& dex_file, SirtRef<DexCache>& dex_cache)
+ void AppendToBootClassPath(const DexFile& dex_file, SirtRef<mirror::DexCache>& dex_cache)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void ConstructFieldMap(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
- Class* c, SafeMap<uint32_t, Field*>& field_map)
+ mirror::Class* c, SafeMap<uint32_t, mirror::Field*>& field_map)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
size_t SizeOfClass(const DexFile& dex_file,
@@ -445,18 +388,20 @@
void LoadClass(const DexFile& dex_file,
const DexFile::ClassDef& dex_class_def,
- SirtRef<Class>& klass,
- ClassLoader* class_loader)
+ SirtRef<mirror::Class>& klass,
+ mirror::ClassLoader* class_loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void LoadField(const DexFile& dex_file, const ClassDataItemIterator& it, SirtRef<Class>& klass,
- SirtRef<Field>& dst) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void LoadField(const DexFile& dex_file, const ClassDataItemIterator& it,
+ SirtRef<mirror::Class>& klass, SirtRef<mirror::Field>& dst)
+ 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_);
+ mirror::AbstractMethod* LoadMethod(Thread* self, const DexFile& dex_file,
+ const ClassDataItemIterator& dex_method,
+ SirtRef<mirror::Class>& klass)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupStaticTrampolines(Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void FixupStaticTrampolines(mirror::Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Finds the associated oat class for a dex_file and descriptor
const OatFile::OatClass* GetOatClass(const DexFile& dex_file, const char* descriptor);
@@ -464,74 +409,75 @@
// Attempts to insert a class into a class table. Returns NULL if
// the class was inserted, otherwise returns an existing class with
// the same descriptor and ClassLoader.
- Class* InsertClass(const StringPiece& descriptor, Class* klass, bool image_class)
+ mirror::Class* InsertClass(const StringPiece& descriptor, mirror::Class* klass, bool image_class)
LOCKS_EXCLUDED(Locks::classlinker_classes_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void RegisterDexFileLocked(const DexFile& dex_file, SirtRef<DexCache>& dex_cache)
+ void RegisterDexFileLocked(const DexFile& dex_file, SirtRef<mirror::DexCache>& dex_cache)
EXCLUSIVE_LOCKS_REQUIRED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool IsDexFileRegisteredLocked(const DexFile& dex_file) const EXCLUSIVE_LOCKS_REQUIRED(dex_lock_);
void RegisterOatFileLocked(const OatFile& oat_file) EXCLUSIVE_LOCKS_REQUIRED(dex_lock_)
EXCLUSIVE_LOCKS_REQUIRED(dex_lock_);
- bool InitializeClass(Class* klass, bool can_run_clinit, bool can_init_statics)
+ bool InitializeClass(mirror::Class* klass, bool can_run_clinit, bool can_init_statics)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool WaitForInitializeClass(Class* klass, Thread* self, ObjectLock& lock);
- bool ValidateSuperClassDescriptors(const Class* klass)
+ bool WaitForInitializeClass(mirror::Class* klass, Thread* self, ObjectLock& lock);
+ bool ValidateSuperClassDescriptors(const mirror::Class* klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool InitializeSuperClass(Class* klass, bool can_run_clinit, bool can_init_fields)
+ bool InitializeSuperClass(mirror::Class* klass, bool can_run_clinit, bool can_init_fields)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Initialize static fields, returns true if fields were initialized.
- bool InitializeStaticFields(Class* klass)
+ bool InitializeStaticFields(mirror::Class* klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool IsSameDescriptorInDifferentClassContexts(const char* descriptor,
- const Class* klass1,
- const Class* klass2)
+ const mirror::Class* klass1,
+ const mirror::Class* klass2)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool IsSameMethodSignatureInDifferentClassContexts(const AbstractMethod* descriptor,
- const Class* klass1,
- const Class* klass2)
+ bool IsSameMethodSignatureInDifferentClassContexts(const mirror::AbstractMethod* method,
+ const mirror::Class* klass1,
+ const mirror::Class* klass2)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkClass(SirtRef<Class>& klass, ObjectArray<Class>* interfaces)
+ bool LinkClass(SirtRef<mirror::Class>& klass, mirror::ObjectArray<mirror::Class>* interfaces)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkSuperClass(SirtRef<Class>& klass)
+ bool LinkSuperClass(SirtRef<mirror::Class>& klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LoadSuperAndInterfaces(SirtRef<Class>& klass, const DexFile& dex_file)
+ bool LoadSuperAndInterfaces(SirtRef<mirror::Class>& klass, const DexFile& dex_file)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkMethods(SirtRef<Class>& klass, ObjectArray<Class>* interfaces)
+ bool LinkMethods(SirtRef<mirror::Class>& klass, mirror::ObjectArray<mirror::Class>* interfaces)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkVirtualMethods(SirtRef<Class>& klass)
+ bool LinkVirtualMethods(SirtRef<mirror::Class>& klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkInterfaceMethods(SirtRef<Class>& klass, ObjectArray<Class>* interfaces)
+ bool LinkInterfaceMethods(SirtRef<mirror::Class>& klass,
+ mirror::ObjectArray<mirror::Class>* interfaces)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkStaticFields(SirtRef<Class>& klass)
+ bool LinkStaticFields(SirtRef<mirror::Class>& klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkInstanceFields(SirtRef<Class>& klass)
+ bool LinkInstanceFields(SirtRef<mirror::Class>& klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool LinkFields(SirtRef<Class>& klass, bool is_static)
+ bool LinkFields(SirtRef<mirror::Class>& klass, bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void CreateReferenceInstanceOffsets(SirtRef<Class>& klass)
+ void CreateReferenceInstanceOffsets(SirtRef<mirror::Class>& klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void CreateReferenceStaticOffsets(SirtRef<Class>& klass)
+ void CreateReferenceStaticOffsets(SirtRef<mirror::Class>& klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void CreateReferenceOffsets(SirtRef<Class>& klass, bool is_static,
+ void CreateReferenceOffsets(SirtRef<mirror::Class>& klass, bool is_static,
uint32_t reference_offsets)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// For use by ImageWriter to find DexCaches for its roots
- const std::vector<DexCache*>& GetDexCaches() {
+ const std::vector<mirror::DexCache*>& GetDexCaches() {
return dex_caches_;
}
@@ -547,28 +493,29 @@
EXCLUSIVE_LOCKS_REQUIRED(dex_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- AbstractMethod* CreateProxyConstructor(Thread* self, SirtRef<Class>& klass, Class* proxy_class)
+ mirror::AbstractMethod* CreateProxyConstructor(Thread* self, SirtRef<mirror::Class>& klass,
+ mirror::Class* proxy_class)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- AbstractMethod* CreateProxyMethod(Thread* self, SirtRef<Class>& klass,
- SirtRef<AbstractMethod>& prototype)
+ mirror::AbstractMethod* CreateProxyMethod(Thread* self, SirtRef<mirror::Class>& klass,
+ SirtRef<mirror::AbstractMethod>& prototype)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
std::vector<const DexFile*> boot_class_path_;
mutable Mutex dex_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
- std::vector<DexCache*> dex_caches_ GUARDED_BY(dex_lock_);
+ std::vector<mirror::DexCache*> dex_caches_ GUARDED_BY(dex_lock_);
std::vector<const OatFile*> oat_files_ GUARDED_BY(dex_lock_);
// multimap from a string hash code of a class descriptor to
- // Class* instances. Results should be compared for a matching
+ // mirror::Class* instances. Results should be compared for a matching
// Class::descriptor_ and Class::class_loader_.
- typedef std::multimap<size_t, Class*> Table;
- Table image_classes_ GUARDED_BY(Locks::classlinker_classes_lock_);
+ typedef std::multimap<size_t, mirror::Class*> Table;
+ Table image_classes_ GUARDED_BY(Locks::classlinker_classes_lock_);
Table classes_ GUARDED_BY(Locks::classlinker_classes_lock_);
- Class* LookupClassLocked(const char* descriptor, const ClassLoader* class_loader,
- size_t hash, const Table& classes)
+ mirror::Class* LookupClassLocked(const char* descriptor, const mirror::ClassLoader* class_loader,
+ size_t hash, const Table& classes)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
EXCLUSIVE_LOCKS_REQUIRED(Locks::classlinker_classes_lock_);
@@ -615,20 +562,14 @@
kJavaLangStackTraceElementArrayClass,
kClassRootsMax,
};
- ObjectArray<Class>* class_roots_;
+ mirror::ObjectArray<mirror::Class>* class_roots_;
- Class* GetClassRoot(ClassRoot class_root)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(class_roots_ != NULL);
- Class* klass = class_roots_->Get(class_root);
- DCHECK(klass != NULL);
- return klass;
- }
+ mirror::Class* GetClassRoot(ClassRoot class_root) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetClassRoot(ClassRoot class_root, Class* klass)
+ void SetClassRoot(ClassRoot class_root, mirror::Class* klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ObjectArray<Class>* GetClassRoots() {
+ mirror::ObjectArray<mirror::Class>* GetClassRoots() {
DCHECK(class_roots_ != NULL);
return class_roots_;
}
@@ -641,7 +582,7 @@
return descriptor;
}
- IfTable* array_iftable_;
+ mirror::IfTable* array_iftable_;
bool init_done_;
bool is_dirty_;
@@ -652,7 +593,7 @@
friend class ImageWriter; // for GetClassRoots
friend class ObjectTest;
FRIEND_TEST(ClassLinkerTest, ClassRootDescriptors);
- FRIEND_TEST(DexCacheTest, Open);
+ FRIEND_TEST(mirror::DexCacheTest, Open);
FRIEND_TEST(ExceptionTest, FindExceptionHandler);
FRIEND_TEST(ObjectTest, AllocObjectArray);
DISALLOW_COPY_AND_ASSIGN(ClassLinker);
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index d32e91e..893e7a4 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -19,13 +19,24 @@
#include <string>
#include "UniquePtr.h"
+#include "class_linker-inl.h"
#include "common_test.h"
-#include "dex_cache.h"
#include "dex_file.h"
#include "heap.h"
+#include "mirror/class-inl.h"
+#include "mirror/dex_cache.h"
+#include "mirror/field-inl.h"
+#include "mirror/abstract_method.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
+#include "mirror/proxy.h"
+#include "mirror/stack_trace_element.h"
#include "runtime_support.h"
#include "sirt_ref.h"
+using namespace art::mirror;
+
namespace art {
class ClassLinkerTest : public CommonTest {
@@ -600,10 +611,10 @@
};
};
-struct MethodClassOffsets : public CheckOffsets<MethodClass> {
- MethodClassOffsets() : CheckOffsets<MethodClass>(true, "Ljava/lang/reflect/Method;") {
+struct MethodClassOffsets : public CheckOffsets<AbstractMethodClass> {
+ MethodClassOffsets() : CheckOffsets<AbstractMethodClass>(true, "Ljava/lang/reflect/Method;") {
// alphabetical references
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(MethodClass, ORDER_BY_SIGNATURE_), "ORDER_BY_SIGNATURE"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(AbstractMethodClass, ORDER_BY_SIGNATURE_), "ORDER_BY_SIGNATURE"));
};
};
diff --git a/src/common_test.h b/src/common_test.h
index 5a5479a..46a8309 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -26,12 +26,12 @@
#include "base/stringprintf.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
-#include "class_loader.h"
#include "compiler.h"
#include "dex_file.h"
#include "gtest/gtest.h"
#include "heap.h"
#include "instruction_set.h"
+#include "mirror/class_loader.h"
#include "oat_file.h"
#include "object_utils.h"
#include "os.h"
@@ -171,7 +171,7 @@
class CommonTest : public testing::Test {
public:
- static void MakeExecutable(const ByteArray* code_array) {
+ static void MakeExecutable(const mirror::ByteArray* code_array) {
CHECK(code_array != NULL);
MakeExecutable(code_array->GetData(), code_array->GetLength());
}
@@ -189,7 +189,7 @@
const uint32_t* mapping_table,
const uint16_t* vmap_table,
const uint8_t* gc_map,
- const AbstractMethod::InvokeStub* invoke_stub) {
+ const mirror::AbstractMethod::InvokeStub* invoke_stub) {
return OatFile::OatMethod(NULL,
reinterpret_cast<uint32_t>(code),
frame_size_in_bytes,
@@ -205,7 +205,7 @@
);
}
- void MakeExecutable(AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ void MakeExecutable(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK(method != NULL);
MethodHelper mh(method);
@@ -215,8 +215,8 @@
const std::vector<uint8_t>& invoke_stub = compiled_invoke_stub->GetCode();
MakeExecutable(invoke_stub);
- const AbstractMethod::InvokeStub* method_invoke_stub =
- reinterpret_cast<const AbstractMethod::InvokeStub*>(
+ const mirror::AbstractMethod::InvokeStub* method_invoke_stub =
+ reinterpret_cast<const mirror::AbstractMethod::InvokeStub*>(
CompiledCode::CodePointer(&invoke_stub[0],
compiled_invoke_stub->GetInstructionSet()));
@@ -224,7 +224,7 @@
<< " invoke_stub=" << reinterpret_cast<void*>(method_invoke_stub);
if (!method->IsAbstract()) {
- const DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
+ const mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
const DexFile& dex_file = *dex_cache->GetDexFile();
const CompiledMethod* compiled_method =
compiler_->GetCompiledMethod(Compiler::MethodReference(&dex_file,
@@ -473,14 +473,14 @@
ScopedLocalRef<jobject> class_loader_local(soa.Env(),
soa.Env()->AllocObject(WellKnownClasses::dalvik_system_PathClassLoader));
jobject class_loader = soa.Env()->NewGlobalRef(class_loader_local.get());
- soa.Self()->SetClassLoaderOverride(soa.Decode<ClassLoader*>(class_loader_local.get()));
+ soa.Self()->SetClassLoaderOverride(soa.Decode<mirror::ClassLoader*>(class_loader_local.get()));
Runtime::Current()->SetCompileTimeClassPath(class_loader, class_path);
return class_loader;
}
- void CompileClass(ClassLoader* class_loader, const char* class_name) {
+ void CompileClass(mirror::ClassLoader* class_loader, const char* class_name) {
std::string class_descriptor(DotToDescriptor(class_name));
- Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
+ mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
CHECK(klass != NULL) << "Class not found " << class_name;
for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
CompileMethod(klass->GetDirectMethod(i));
@@ -490,7 +490,7 @@
}
}
- void CompileMethod(AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ void CompileMethod(mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK(method != NULL);
compiler_->CompileOne(method);
MakeExecutable(method);
@@ -498,29 +498,29 @@
MakeExecutable(runtime_->GetJniDlsymLookupStub());
}
- void CompileDirectMethod(ClassLoader* class_loader,
+ void CompileDirectMethod(mirror::ClassLoader* class_loader,
const char* class_name,
const char* method_name,
const char* signature)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::string class_descriptor(DotToDescriptor(class_name));
- Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
+ mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
CHECK(klass != NULL) << "Class not found " << class_name;
- AbstractMethod* method = klass->FindDirectMethod(method_name, signature);
+ mirror::AbstractMethod* method = klass->FindDirectMethod(method_name, signature);
CHECK(method != NULL) << "Direct method not found: "
<< class_name << "." << method_name << signature;
CompileMethod(method);
}
- void CompileVirtualMethod(ClassLoader* class_loader,
+ void CompileVirtualMethod(mirror::ClassLoader* class_loader,
const char* class_name,
const char* method_name,
const char* signature)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::string class_descriptor(DotToDescriptor(class_name));
- Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
+ mirror::Class* klass = class_linker_->FindClass(class_descriptor.c_str(), class_loader);
CHECK(klass != NULL) << "Class not found " << class_name;
- AbstractMethod* method = klass->FindVirtualMethod(method_name, signature);
+ mirror::AbstractMethod* method = klass->FindVirtualMethod(method_name, signature);
CHECK(method != NULL) << "Virtual method not found: "
<< class_name << "." << method_name << signature;
CompileMethod(method);
diff --git a/src/common_throws.cc b/src/common_throws.cc
index cefc4ab..734d544 100644
--- a/src/common_throws.cc
+++ b/src/common_throws.cc
@@ -17,8 +17,12 @@
#include "common_throws.h"
#include "base/logging.h"
+#include "class_linker-inl.h"
#include "dex_instruction.h"
#include "invoke_type.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
#include "object_utils.h"
#include "thread.h"
@@ -26,7 +30,7 @@
namespace art {
-static void AddReferrerLocation(std::ostream& os, const AbstractMethod* referrer)
+static void AddReferrerLocation(std::ostream& os, const mirror::AbstractMethod* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (referrer != NULL) {
ClassHelper kh(referrer->GetDeclaringClass());
@@ -37,7 +41,7 @@
}
}
-static void AddReferrerLocationFromClass(std::ostream& os, Class* referrer)
+static void AddReferrerLocationFromClass(std::ostream& os, mirror::Class* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (referrer != NULL) {
ClassHelper kh(referrer);
@@ -51,16 +55,16 @@
// NullPointerException
-void ThrowNullPointerExceptionForFieldAccess(Field* field, bool is_read) {
+void ThrowNullPointerExceptionForFieldAccess(mirror::Field* field, bool is_read) {
std::ostringstream msg;
msg << "Attempt to " << (is_read ? "read from" : "write to")
<< " field '" << PrettyField(field, true) << "' on a null object reference";
Thread::Current()->ThrowNewException("Ljava/lang/NullPointerException;", msg.str().c_str());
}
-void ThrowNullPointerExceptionForMethodAccess(AbstractMethod* caller, uint32_t method_idx,
+void ThrowNullPointerExceptionForMethodAccess(mirror::AbstractMethod* caller, uint32_t method_idx,
InvokeType type) {
- DexCache* dex_cache = caller->GetDeclaringClass()->GetDexCache();
+ mirror::DexCache* dex_cache = caller->GetDeclaringClass()->GetDexCache();
const DexFile& dex_file = *dex_cache->GetDexFile();
std::ostringstream msg;
msg << "Attempt to invoke " << type << " method '"
@@ -68,7 +72,7 @@
Thread::Current()->ThrowNewException("Ljava/lang/NullPointerException;", msg.str().c_str());
}
-void ThrowNullPointerExceptionFromDexPC(AbstractMethod* throw_method, uint32_t dex_pc) {
+void ThrowNullPointerExceptionFromDexPC(mirror::AbstractMethod* throw_method, uint32_t dex_pc) {
const DexFile::CodeItem* code = MethodHelper(throw_method).GetCodeItem();
CHECK_LT(dex_pc, code->insns_size_in_code_units_);
const Instruction* instr = Instruction::At(&code->insns_[dex_pc]);
@@ -93,7 +97,7 @@
case Instruction::IGET_BYTE:
case Instruction::IGET_CHAR:
case Instruction::IGET_SHORT: {
- Field* field =
+ mirror::Field* field =
Runtime::Current()->GetClassLinker()->ResolveField(dec_insn.vC, throw_method, false);
ThrowNullPointerExceptionForFieldAccess(field, true /* read */);
break;
@@ -105,7 +109,7 @@
case Instruction::IPUT_BYTE:
case Instruction::IPUT_CHAR:
case Instruction::IPUT_SHORT: {
- Field* field =
+ mirror::Field* field =
Runtime::Current()->GetClassLinker()->ResolveField(dec_insn.vC, throw_method, false);
ThrowNullPointerExceptionForFieldAccess(field, false /* write */);
break;
@@ -149,7 +153,7 @@
// IllegalAccessError
-void ThrowIllegalAccessErrorClass(Class* referrer, Class* accessed) {
+void ThrowIllegalAccessErrorClass(mirror::Class* referrer, mirror::Class* accessed) {
std::ostringstream msg;
msg << "Illegal class access: '" << PrettyDescriptor(referrer) << "' attempting to access '"
<< PrettyDescriptor(accessed) << "'";
@@ -157,9 +161,9 @@
Thread::Current()->ThrowNewException("Ljava/lang/IllegalAccessError;", msg.str().c_str());
}
-void ThrowIllegalAccessErrorClassForMethodDispatch(Class* referrer, Class* accessed,
- const AbstractMethod* caller,
- const AbstractMethod* called,
+void ThrowIllegalAccessErrorClassForMethodDispatch(mirror::Class* referrer, mirror::Class* accessed,
+ const mirror::AbstractMethod* caller,
+ const mirror::AbstractMethod* called,
InvokeType type) {
std::ostringstream msg;
msg << "Illegal class access ('" << PrettyDescriptor(referrer) << "' attempting to access '"
@@ -169,7 +173,7 @@
Thread::Current()->ThrowNewException("Ljava/lang/IllegalAccessError;", msg.str().c_str());
}
-void ThrowIllegalAccessErrorMethod(Class* referrer, AbstractMethod* accessed) {
+void ThrowIllegalAccessErrorMethod(mirror::Class* referrer, mirror::AbstractMethod* accessed) {
std::ostringstream msg;
msg << "Method '" << PrettyMethod(accessed) << "' is inaccessible to class '"
<< PrettyDescriptor(referrer) << "'";
@@ -177,7 +181,7 @@
Thread::Current()->ThrowNewException("Ljava/lang/IllegalAccessError;", msg.str().c_str());
}
-void ThrowIllegalAccessErrorField(Class* referrer, Field* accessed) {
+void ThrowIllegalAccessErrorField(mirror::Class* referrer, mirror::Field* accessed) {
std::ostringstream msg;
msg << "Field '" << PrettyField(accessed, false) << "' is inaccessible to class '"
<< PrettyDescriptor(referrer) << "'";
@@ -185,7 +189,8 @@
Thread::Current()->ThrowNewException("Ljava/lang/IllegalAccessError;", msg.str().c_str());
}
-void ThrowIllegalAccessErrorFinalField(const AbstractMethod* referrer, Field* accessed) {
+void ThrowIllegalAccessErrorFinalField(const mirror::AbstractMethod* referrer,
+ mirror::Field* accessed) {
std::ostringstream msg;
msg << "Final field '" << PrettyField(accessed, false) << "' cannot be written to by method '"
<< PrettyMethod(referrer) << "'";
@@ -196,7 +201,8 @@
// IncompatibleClassChangeError
void ThrowIncompatibleClassChangeError(InvokeType expected_type, InvokeType found_type,
- AbstractMethod* method, const AbstractMethod* referrer) {
+ mirror::AbstractMethod* method,
+ const mirror::AbstractMethod* referrer) {
std::ostringstream msg;
msg << "The method '" << PrettyMethod(method) << "' was expected to be of type "
<< expected_type << " but instead was found to be of type " << found_type;
@@ -205,9 +211,9 @@
msg.str().c_str());
}
-void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(const AbstractMethod* interface_method,
- Object* this_object,
- const AbstractMethod* referrer) {
+void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(const mirror::AbstractMethod* interface_method,
+ mirror::Object* this_object,
+ const mirror::AbstractMethod* referrer) {
// Referrer is calling interface_method on this_object, however, the interface_method isn't
// implemented by this_object.
CHECK(this_object != NULL);
@@ -221,8 +227,8 @@
msg.str().c_str());
}
-void ThrowIncompatibleClassChangeErrorField(const Field* resolved_field, bool is_static,
- const AbstractMethod* referrer) {
+void ThrowIncompatibleClassChangeErrorField(const mirror::Field* resolved_field, bool is_static,
+ const mirror::AbstractMethod* referrer) {
std::ostringstream msg;
msg << "Expected '" << PrettyField(resolved_field) << "' to be a "
<< (is_static ? "static" : "instance") << " field" << " rather than a "
@@ -234,8 +240,8 @@
// NoSuchMethodError
-void ThrowNoSuchMethodError(InvokeType type, Class* c, const StringPiece& name,
- const StringPiece& signature, const AbstractMethod* referrer) {
+void ThrowNoSuchMethodError(InvokeType type, mirror::Class* c, const StringPiece& name,
+ const StringPiece& signature, const mirror::AbstractMethod* referrer) {
std::ostringstream msg;
ClassHelper kh(c);
msg << "No " << type << " method " << name << signature
@@ -244,8 +250,8 @@
Thread::Current()->ThrowNewException("Ljava/lang/NoSuchMethodError;", msg.str().c_str());
}
-void ThrowNoSuchMethodError(uint32_t method_idx, const AbstractMethod* referrer) {
- DexCache* dex_cache = referrer->GetDeclaringClass()->GetDexCache();
+void ThrowNoSuchMethodError(uint32_t method_idx, const mirror::AbstractMethod* referrer) {
+ mirror::DexCache* dex_cache = referrer->GetDeclaringClass()->GetDexCache();
const DexFile& dex_file = *dex_cache->GetDexFile();
std::ostringstream msg;
msg << "No method '" << PrettyMethod(method_idx, dex_file, true) << "'";
diff --git a/src/common_throws.h b/src/common_throws.h
index 33769c4..9e28bd7 100644
--- a/src/common_throws.h
+++ b/src/common_throws.h
@@ -18,62 +18,73 @@
#define ART_SRC_COMMON_THROWS_H_
#include "base/mutex.h"
-#include "object.h"
+#include "invoke_type.h"
namespace art {
+namespace mirror {
+class AbstractMethod;
+class Class;
+class Field;
+class Object;
+} // namespace mirror
+class StringPiece;
// NullPointerException
-void ThrowNullPointerExceptionForFieldAccess(Field* field, bool is_read)
+void ThrowNullPointerExceptionForFieldAccess(mirror::Field* field, bool is_read)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-void ThrowNullPointerExceptionForMethodAccess(AbstractMethod* caller, uint32_t method_idx, InvokeType type)
+void ThrowNullPointerExceptionForMethodAccess(mirror::AbstractMethod* caller, uint32_t method_idx,
+ InvokeType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-void ThrowNullPointerExceptionFromDexPC(AbstractMethod* throw_method, uint32_t dex_pc)
+void ThrowNullPointerExceptionFromDexPC(mirror::AbstractMethod* throw_method, uint32_t dex_pc)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// IllegalAccessError
-void ThrowIllegalAccessErrorClass(Class* referrer, Class* accessed)
+void ThrowIllegalAccessErrorClass(mirror::Class* referrer, mirror::Class* accessed)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-void ThrowIllegalAccessErrorClassForMethodDispatch(Class* referrer, Class* accessed,
- const AbstractMethod* caller, const AbstractMethod* called,
+void ThrowIllegalAccessErrorClassForMethodDispatch(mirror::Class* referrer, mirror::Class* accessed,
+ const mirror::AbstractMethod* caller,
+ const mirror::AbstractMethod* called,
InvokeType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-void ThrowIllegalAccessErrorMethod(Class* referrer, AbstractMethod* accessed)
+void ThrowIllegalAccessErrorMethod(mirror::Class* referrer, mirror::AbstractMethod* accessed)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-void ThrowIllegalAccessErrorField(Class* referrer, Field* accessed)
+void ThrowIllegalAccessErrorField(mirror::Class* referrer, mirror::Field* accessed)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-void ThrowIllegalAccessErrorFinalField(const AbstractMethod* referrer, Field* accessed)
+void ThrowIllegalAccessErrorFinalField(const mirror::AbstractMethod* referrer,
+ mirror::Field* accessed)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// IncompatibleClassChangeError
void ThrowIncompatibleClassChangeError(InvokeType expected_type, InvokeType found_type,
- AbstractMethod* method, const AbstractMethod* referrer)
+ mirror::AbstractMethod* method,
+ const mirror::AbstractMethod* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(const AbstractMethod* interface_method,
- Object* this_object,
- const AbstractMethod* referrer)
+void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(const mirror::AbstractMethod* interface_method,
+ mirror::Object* this_object,
+ const mirror::AbstractMethod* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-void ThrowIncompatibleClassChangeErrorField(const Field* resolved_field, bool is_static,
- const AbstractMethod* referrer)
+void ThrowIncompatibleClassChangeErrorField(const mirror::Field* resolved_field, bool is_static,
+ const mirror::AbstractMethod* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// NoSuchMethodError
-void ThrowNoSuchMethodError(InvokeType type, Class* c, const StringPiece& name,
- const StringPiece& signature, const AbstractMethod* referrer)
+void ThrowNoSuchMethodError(InvokeType type, mirror::Class* c, const StringPiece& name,
+ const StringPiece& signature, const mirror::AbstractMethod* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-void ThrowNoSuchMethodError(uint32_t method_idx, const AbstractMethod* referrer)
+void ThrowNoSuchMethodError(uint32_t method_idx, const mirror::AbstractMethod* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
} // namespace art
diff --git a/src/compiled_class.h b/src/compiled_class.h
index 97dd8ee..f050ee6 100644
--- a/src/compiled_class.h
+++ b/src/compiled_class.h
@@ -17,19 +17,19 @@
#ifndef ART_SRC_COMPILED_CLASS_H_
#define ART_SRC_COMPILED_CLASS_H_
-#include "object.h"
+#include "mirror/class.h"
namespace art {
class CompiledClass {
public:
- explicit CompiledClass(Class::Status status) : status_(status) {}
+ explicit CompiledClass(mirror::Class::Status status) : status_(status) {}
~CompiledClass() {}
- Class::Status GetStatus() const {
+ mirror::Class::Status GetStatus() const {
return status_;
}
private:
- const Class::Status status_;
+ const mirror::Class::Status status_;
};
} // namespace art
diff --git a/src/compiler.cc b/src/compiler.cc
index 18460ce..903b70a 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -23,15 +23,22 @@
#include "base/stl_util.h"
#include "class_linker.h"
-#include "class_loader.h"
-#include "dex_cache.h"
#include "jni_internal.h"
#include "oat_compilation_unit.h"
#include "oat_file.h"
#include "oat/runtime/stub.h"
#include "object_utils.h"
#include "runtime.h"
+#include "gc/card_table-inl.h"
#include "gc/space.h"
+#include "mirror/class_loader.h"
+#include "mirror/class-inl.h"
+#include "mirror/dex_cache.h"
+#include "mirror/field-inl.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
+#include "mirror/throwable.h"
#include "scoped_thread_state_change.h"
#include "ScopedLocalRef.h"
#include "thread.h"
@@ -431,7 +438,7 @@
return res;
}
-ByteArray* Compiler::CreateResolutionStub(InstructionSet instruction_set,
+mirror::ByteArray* Compiler::CreateResolutionStub(InstructionSet instruction_set,
Runtime::TrampolineType type) {
switch (instruction_set) {
case kArm:
@@ -447,7 +454,7 @@
}
}
-ByteArray* Compiler::CreateJniDlsymLookupStub(InstructionSet instruction_set) {
+mirror::ByteArray* Compiler::CreateJniDlsymLookupStub(InstructionSet instruction_set) {
switch (instruction_set) {
case kArm:
case kThumb2:
@@ -462,7 +469,7 @@
}
}
-ByteArray* Compiler::CreateAbstractMethodErrorStub(InstructionSet instruction_set) {
+mirror::ByteArray* Compiler::CreateAbstractMethodErrorStub(InstructionSet instruction_set) {
switch (instruction_set) {
case kArm:
case kThumb2:
@@ -497,7 +504,7 @@
}
}
-void Compiler::CompileOne(const AbstractMethod* method) {
+void Compiler::CompileOne(const mirror::AbstractMethod* method) {
DCHECK(!Runtime::Current()->IsStarted());
Thread* self = Thread::Current();
jobject class_loader;
@@ -566,12 +573,12 @@
bool Compiler::CanAssumeTypeIsPresentInDexCache(const DexFile& dex_file,
uint32_t type_idx) {
ScopedObjectAccess soa(Thread::Current());
- DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
+ mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
if (!IsImage()) {
stats_->TypeNotInDexCache();
return false;
}
- Class* resolved_class = dex_cache->GetResolvedType(type_idx);
+ mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
if (resolved_class == NULL) {
stats_->TypeNotInDexCache();
return false;
@@ -593,7 +600,7 @@
if (IsImage()) {
// We resolve all const-string strings when building for the image.
ScopedObjectAccess soa(Thread::Current());
- DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
+ mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
Runtime::Current()->GetClassLinker()->ResolveString(dex_file, string_idx, dex_cache);
result = true;
}
@@ -608,15 +615,15 @@
bool Compiler::CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexFile& dex_file,
uint32_t type_idx) {
ScopedObjectAccess soa(Thread::Current());
- DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
+ mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
// Get type from dex cache assuming it was populated by the verifier
- Class* resolved_class = dex_cache->GetResolvedType(type_idx);
+ mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
if (resolved_class == NULL) {
stats_->TypeNeedsAccessCheck();
return false; // Unknown class needs access checks.
}
const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
- Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
+ mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
if (referrer_class == NULL) {
stats_->TypeNeedsAccessCheck();
return false; // Incomplete referrer knowledge needs access check.
@@ -636,15 +643,15 @@
const DexFile& dex_file,
uint32_t type_idx) {
ScopedObjectAccess soa(Thread::Current());
- DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
+ mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
// Get type from dex cache assuming it was populated by the verifier.
- Class* resolved_class = dex_cache->GetResolvedType(type_idx);
+ mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
if (resolved_class == NULL) {
stats_->TypeNeedsAccessCheck();
return false; // Unknown class needs access checks.
}
const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
- Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
+ mirror::Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
if (referrer_class == NULL) {
stats_->TypeNeedsAccessCheck();
return false; // Incomplete referrer knowledge needs access check.
@@ -660,33 +667,33 @@
return result;
}
-static Class* ComputeCompilingMethodsClass(ScopedObjectAccess& soa,
- OatCompilationUnit* mUnit)
+static mirror::Class* ComputeCompilingMethodsClass(ScopedObjectAccess& soa,
+ OatCompilationUnit* mUnit)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_);
- ClassLoader* class_loader = soa.Decode<ClassLoader*>(mUnit->class_loader_);
+ mirror::DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_);
+ mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->class_loader_);
const DexFile::MethodId& referrer_method_id = mUnit->dex_file_->GetMethodId(mUnit->method_idx_);
return mUnit->class_linker_->ResolveType(*mUnit->dex_file_, referrer_method_id.class_idx_,
dex_cache, class_loader);
}
-static Field* ComputeFieldReferencedFromCompilingMethod(ScopedObjectAccess& soa,
- OatCompilationUnit* mUnit,
- uint32_t field_idx)
+static mirror::Field* ComputeFieldReferencedFromCompilingMethod(ScopedObjectAccess& soa,
+ OatCompilationUnit* mUnit,
+ uint32_t field_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_);
- ClassLoader* class_loader = soa.Decode<ClassLoader*>(mUnit->class_loader_);
+ mirror::DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_);
+ mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->class_loader_);
return mUnit->class_linker_->ResolveField(*mUnit->dex_file_, field_idx, dex_cache,
class_loader, false);
}
-static AbstractMethod* ComputeMethodReferencedFromCompilingMethod(ScopedObjectAccess& soa,
- OatCompilationUnit* mUnit,
- uint32_t method_idx,
- InvokeType type)
+static mirror::AbstractMethod* ComputeMethodReferencedFromCompilingMethod(ScopedObjectAccess& soa,
+ OatCompilationUnit* mUnit,
+ uint32_t method_idx,
+ InvokeType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_);
- ClassLoader* class_loader = soa.Decode<ClassLoader*>(mUnit->class_loader_);
+ mirror::DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_);
+ mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(mUnit->class_loader_);
return mUnit->class_linker_->ResolveMethod(*mUnit->dex_file_, method_idx, dex_cache,
class_loader, NULL, type);
}
@@ -698,11 +705,11 @@
field_offset = -1;
is_volatile = true;
// Try to resolve field and ignore if an Incompatible Class Change Error (ie is static).
- Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx);
+ mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx);
if (resolved_field != NULL && !resolved_field->IsStatic()) {
- Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
+ mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
if (referrer_class != NULL) {
- Class* fields_class = resolved_field->GetDeclaringClass();
+ mirror::Class* fields_class = resolved_field->GetDeclaringClass();
bool access_ok = referrer_class->CanAccess(fields_class) &&
referrer_class->CanAccessMember(fields_class,
resolved_field->GetAccessFlags());
@@ -711,7 +718,7 @@
// protected field being made public by a sub-class. Resort to the dex file to determine
// the correct class for the access check.
const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile();
- Class* dex_fields_class = mUnit->class_linker_->ResolveType(dex_file,
+ mirror::Class* dex_fields_class = mUnit->class_linker_->ResolveType(dex_file,
dex_file.GetFieldId(field_idx).class_idx_,
referrer_class);
access_ok = referrer_class->CanAccess(dex_fields_class) &&
@@ -746,11 +753,11 @@
is_referrers_class = false;
is_volatile = true;
// Try to resolve field and ignore if an Incompatible Class Change Error (ie isn't static).
- Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx);
+ mirror::Field* resolved_field = ComputeFieldReferencedFromCompilingMethod(soa, mUnit, field_idx);
if (resolved_field != NULL && resolved_field->IsStatic()) {
- Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
+ mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
if (referrer_class != NULL) {
- Class* fields_class = resolved_field->GetDeclaringClass();
+ mirror::Class* fields_class = resolved_field->GetDeclaringClass();
if (fields_class == referrer_class) {
is_referrers_class = true; // implies no worrying about class initialization
field_offset = resolved_field->GetOffset().Int32Value();
@@ -767,7 +774,7 @@
// the correct class for the access check. Don't change the field's class as that is
// used to identify the SSB.
const DexFile& dex_file = *referrer_class->GetDexCache()->GetDexFile();
- Class* dex_fields_class =
+ mirror::Class* dex_fields_class =
mUnit->class_linker_->ResolveType(dex_file,
dex_file.GetFieldId(field_idx).class_idx_,
referrer_class);
@@ -781,7 +788,7 @@
// in its static storage base (which may fail if it doesn't have a slot for it)
// TODO: for images we can elide the static storage base null check
// if we know there's a non-null entry in the image
- DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_);
+ mirror::DexCache* dex_cache = mUnit->class_linker_->FindDexCache(*mUnit->dex_file_);
if (fields_class->GetDexCache() == dex_cache) {
// common case where the dex cache of both the referrer and the field are the same,
// no need to search the dex file
@@ -820,7 +827,8 @@
return false; // Incomplete knowledge needs slow path.
}
-void Compiler::GetCodeAndMethodForDirectCall(InvokeType type, InvokeType sharp_type, AbstractMethod* method,
+void Compiler::GetCodeAndMethodForDirectCall(InvokeType type, InvokeType sharp_type,
+ mirror::AbstractMethod* method,
uintptr_t& direct_code, uintptr_t& direct_method) {
// For direct and static methods compute possible direct_code and direct_method values, ie
// an address for the Method* being invoked and an address of the code for that Method*.
@@ -876,15 +884,15 @@
vtable_idx = -1;
direct_code = 0;
direct_method = 0;
- AbstractMethod* resolved_method =
+ mirror::AbstractMethod* resolved_method =
ComputeMethodReferencedFromCompilingMethod(soa, mUnit, method_idx, type);
if (resolved_method != NULL) {
// Don't try to fast-path if we don't understand the caller's class or this appears to be an
// Incompatible Class Change Error.
- Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
+ mirror::Class* referrer_class = ComputeCompilingMethodsClass(soa, mUnit);
bool icce = resolved_method->CheckIncompatibleClassChange(type);
if (referrer_class != NULL && !icce) {
- Class* methods_class = resolved_method->GetDeclaringClass();
+ mirror::Class* methods_class = resolved_method->GetDeclaringClass();
if (!referrer_class->CanAccess(methods_class) ||
!referrer_class->CanAccessMember(methods_class,
resolved_method->GetAccessFlags())) {
@@ -1068,7 +1076,7 @@
// classes found in the boot classpath. Since at runtime we will
// select the class from the boot classpath, do not attempt to resolve
// or compile it now.
-static bool SkipClass(ClassLoader* class_loader,
+static bool SkipClass(mirror::ClassLoader* class_loader,
const DexFile& dex_file,
const DexFile::ClassDef& class_def)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -1077,7 +1085,7 @@
}
const char* descriptor = dex_file.GetClassDescriptor(class_def);
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Class* klass = class_linker->FindClass(descriptor, NULL);
+ mirror::Class* klass = class_linker->FindClass(descriptor, NULL);
if (klass == NULL) {
Thread* self = Thread::Current();
CHECK(self->IsExceptionPending());
@@ -1090,7 +1098,7 @@
static void ResolveClassFieldsAndMethods(const CompilationContext* context, size_t class_def_index)
LOCKS_EXCLUDED(Locks::mutator_lock_) {
ScopedObjectAccess soa(Thread::Current());
- ClassLoader* class_loader = soa.Decode<ClassLoader*>(context->GetClassLoader());
+ mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(context->GetClassLoader());
const DexFile& dex_file = *context->GetDexFile();
// Method and Field are the worst. We can't resolve without either
@@ -1115,11 +1123,11 @@
}
Thread* self = Thread::Current();
ClassLinker* class_linker = context->GetClassLinker();
- DexCache* dex_cache = class_linker->FindDexCache(dex_file);
+ mirror::DexCache* dex_cache = class_linker->FindDexCache(dex_file);
ClassDataItemIterator it(dex_file, class_data);
while (it.HasNextStaticField()) {
- Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
- class_loader, true);
+ mirror::Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
+ class_loader, true);
if (field == NULL) {
CHECK(self->IsExceptionPending());
self->ClearException();
@@ -1134,8 +1142,8 @@
requires_constructor_barrier = true;
}
- Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
- class_loader, false);
+ mirror::Field* field = class_linker->ResolveField(dex_file, it.GetMemberIndex(), dex_cache,
+ class_loader, false);
if (field == NULL) {
CHECK(self->IsExceptionPending());
self->ClearException();
@@ -1147,9 +1155,9 @@
class_def_index);
}
while (it.HasNextDirectMethod()) {
- AbstractMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache,
- class_loader, NULL,
- it.GetMethodInvokeType(class_def));
+ mirror::AbstractMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
+ dex_cache, class_loader, NULL,
+ it.GetMethodInvokeType(class_def));
if (method == NULL) {
CHECK(self->IsExceptionPending());
self->ClearException();
@@ -1157,9 +1165,9 @@
it.Next();
}
while (it.HasNextVirtualMethod()) {
- AbstractMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(), dex_cache,
- class_loader, NULL,
- it.GetMethodInvokeType(class_def));
+ mirror::AbstractMethod* method = class_linker->ResolveMethod(dex_file, it.GetMemberIndex(),
+ dex_cache, class_loader, NULL,
+ it.GetMethodInvokeType(class_def));
if (method == NULL) {
CHECK(self->IsExceptionPending());
self->ClearException();
@@ -1175,9 +1183,9 @@
ScopedObjectAccess soa(Thread::Current());
ClassLinker* class_linker = context->GetClassLinker();
const DexFile& dex_file = *context->GetDexFile();
- DexCache* dex_cache = class_linker->FindDexCache(dex_file);
- ClassLoader* class_loader = soa.Decode<ClassLoader*>(context->GetClassLoader());
- Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader);
+ mirror::DexCache* dex_cache = class_linker->FindDexCache(dex_file);
+ mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(context->GetClassLoader());
+ mirror::Class* klass = class_linker->ResolveType(dex_file, type_idx, dex_cache, class_loader);
if (klass == NULL) {
CHECK(soa.Self()->IsExceptionPending());
@@ -1214,9 +1222,9 @@
ScopedObjectAccess soa(Thread::Current());
const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index);
const char* descriptor = context->GetDexFile()->GetClassDescriptor(class_def);
- Class* klass =
+ mirror::Class* klass =
context->GetClassLinker()->FindClass(descriptor,
- soa.Decode<ClassLoader*>(context->GetClassLoader()));
+ soa.Decode<mirror::ClassLoader*>(context->GetClassLoader()));
if (klass == NULL) {
Thread* self = Thread::Current();
CHECK(self->IsExceptionPending());
@@ -1227,11 +1235,11 @@
* This is to ensure the class is structurally sound for compilation. An unsound class
* will be rejected by the verifier and later skipped during compilation in the compiler.
*/
- DexCache* dex_cache = context->GetClassLinker()->FindDexCache(*context->GetDexFile());
+ mirror::DexCache* dex_cache = context->GetClassLinker()->FindDexCache(*context->GetDexFile());
std::string error_msg;
if (verifier::MethodVerifier::VerifyClass(context->GetDexFile(),
dex_cache,
- soa.Decode<ClassLoader*>(context->GetClassLoader()),
+ soa.Decode<mirror::ClassLoader*>(context->GetClassLoader()),
class_def_index, error_msg) ==
verifier::MethodVerifier::kHardFailure) {
const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index);
@@ -1446,9 +1454,9 @@
LOCKS_EXCLUDED(Locks::mutator_lock_) {
const DexFile::ClassDef& class_def = context->GetDexFile()->GetClassDef(class_def_index);
ScopedObjectAccess soa(Thread::Current());
- ClassLoader* class_loader = soa.Decode<ClassLoader*>(context->GetClassLoader());
+ mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(context->GetClassLoader());
const char* descriptor = context->GetDexFile()->GetClassDescriptor(class_def);
- Class* klass = context->GetClassLinker()->FindClass(descriptor, class_loader);
+ mirror::Class* klass = context->GetClassLinker()->FindClass(descriptor, class_loader);
Thread* self = Thread::Current();
bool compiling_boot = Runtime::Current()->GetHeap()->GetSpaces().size() == 1;
bool can_init_static_fields = compiling_boot &&
@@ -1480,10 +1488,10 @@
LOG(INFO) << "Initializing: " << descriptor;
if (StringPiece(descriptor) == "Ljava/lang/Void;"){
// Hand initialize j.l.Void to avoid Dex file operations in un-started runtime.
- ObjectArray<Field>* fields = klass->GetSFields();
+ mirror::ObjectArray<mirror::Field>* fields = klass->GetSFields();
CHECK_EQ(fields->GetLength(), 1);
fields->Get(0)->SetObj(klass, context->GetClassLinker()->FindPrimitiveClass('V'));
- klass->SetStatus(Class::kStatusInitialized);
+ klass->SetStatus(mirror::Class::kStatusInitialized);
} else {
context->GetClassLinker()->EnsureInitialized(klass, true, can_init_static_fields);
}
@@ -1497,7 +1505,7 @@
}
}
// Record the final class status if necessary.
- Class::Status status = klass->GetStatus();
+ mirror::Class::Status status = klass->GetStatus();
Compiler::ClassReference ref(context->GetDexFile(), class_def_index);
CompiledClass* compiled_class = context->GetCompiler()->GetCompiledClass(ref);
if (compiled_class == NULL) {
@@ -1550,7 +1558,7 @@
const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
{
ScopedObjectAccess soa(Thread::Current());
- ClassLoader* class_loader = soa.Decode<ClassLoader*>(context->GetClassLoader());
+ mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(context->GetClassLoader());
if (SkipClass(class_loader, dex_file, class_def)) {
return;
}
diff --git a/src/compiler.h b/src/compiler.h
index 13130d7..0f99f4d 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -24,12 +24,10 @@
#include "base/mutex.h"
#include "compiled_class.h"
#include "compiled_method.h"
-#include "dex_cache.h"
#include "dex_file.h"
#include "instruction_set.h"
#include "invoke_type.h"
#include "oat_file.h"
-#include "object.h"
#include "runtime.h"
#include "safe_map.h"
#include "thread_pool.h"
@@ -79,7 +77,7 @@
LOCKS_EXCLUDED(Locks::mutator_lock_);
// Compile a single Method
- void CompileOne(const AbstractMethod* method)
+ void CompileOne(const mirror::AbstractMethod* method)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool IsDebuggingSupported() {
@@ -101,16 +99,16 @@
CompilerTls* GetTls();
// Stub to throw AbstractMethodError
- static ByteArray* CreateAbstractMethodErrorStub(InstructionSet instruction_set)
+ static mirror::ByteArray* CreateAbstractMethodErrorStub(InstructionSet instruction_set)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Generate the trampoline that's invoked by unresolved direct methods
- static ByteArray* CreateResolutionStub(InstructionSet instruction_set,
- Runtime::TrampolineType type)
+ static mirror::ByteArray* CreateResolutionStub(InstructionSet instruction_set,
+ Runtime::TrampolineType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static ByteArray* CreateJniDlsymLookupStub(InstructionSet instruction_set)
+ static mirror::ByteArray* CreateJniDlsymLookupStub(InstructionSet instruction_set)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// A class is uniquely located by its DexFile and the class_defs_ table index into that DexFile
@@ -273,7 +271,8 @@
private:
// Compute constant code and method pointers when possible
- void GetCodeAndMethodForDirectCall(InvokeType type, InvokeType sharp_type, AbstractMethod* method,
+ void GetCodeAndMethodForDirectCall(InvokeType type, InvokeType sharp_type,
+ mirror::AbstractMethod* method,
uintptr_t& direct_code, uintptr_t& direct_method)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -397,11 +396,11 @@
CompilerEnableAutoElfLoadingFn compiler_enable_auto_elf_loading_;
typedef const void* (*CompilerGetMethodCodeAddrFn)
- (const Compiler& compiler, const CompiledMethod* cm, const AbstractMethod* method);
+ (const Compiler& compiler, const CompiledMethod* cm, const mirror::AbstractMethod* method);
CompilerGetMethodCodeAddrFn compiler_get_method_code_addr_;
- typedef const AbstractMethod::InvokeStub* (*CompilerGetMethodInvokeStubAddrFn)
- (const Compiler& compiler, const CompiledInvokeStub* cm, const AbstractMethod* method);
+ typedef const mirror::AbstractMethod::InvokeStub* (*CompilerGetMethodInvokeStubAddrFn)
+ (const Compiler& compiler, const CompiledInvokeStub* cm, const mirror::AbstractMethod* method);
CompilerGetMethodInvokeStubAddrFn compiler_get_method_invoke_stub_addr_;
diff --git a/src/compiler/codegen/arm/call_arm.cc b/src/compiler/codegen/arm/call_arm.cc
index cb3af5e..47306f4 100644
--- a/src/compiler/codegen/arm/call_arm.cc
+++ b/src/compiler/codegen/arm/call_arm.cc
@@ -489,7 +489,7 @@
GenNullCheck(cu, rl_src.s_reg_low, r0, opt_flags);
LoadWordDisp(cu, rARM_SELF, Thread::ThinLockIdOffset().Int32Value(), r2);
NewLIR3(cu, kThumb2Ldrex, r1, r0,
- Object::MonitorOffset().Int32Value() >> 2); // Get object->lock
+ mirror::Object::MonitorOffset().Int32Value() >> 2); // Get object->lock
// Align owner
OpRegImm(cu, kOpLsl, r2, LW_LOCK_OWNER_SHIFT);
// Is lock unheld on lock or held by us (==thread_id) on unlock?
@@ -498,7 +498,7 @@
OpRegImm(cu, kOpCmp, r1, 0);
OpIT(cu, kCondEq, "");
NewLIR4(cu, kThumb2Strex, r1, r2, r0,
- Object::MonitorOffset().Int32Value() >> 2);
+ mirror::Object::MonitorOffset().Int32Value() >> 2);
OpRegImm(cu, kOpCmp, r1, 0);
OpIT(cu, kCondNe, "T");
// Go expensive route - artLockObjectFromCode(self, obj);
@@ -522,7 +522,7 @@
LoadValueDirectFixed(cu, rl_src, r0); // Get obj
LockCallTemps(cu); // Prepare for explicit register usage
GenNullCheck(cu, rl_src.s_reg_low, r0, opt_flags);
- LoadWordDisp(cu, r0, Object::MonitorOffset().Int32Value(), r1); // Get lock
+ LoadWordDisp(cu, r0, mirror::Object::MonitorOffset().Int32Value(), r1); // Get lock
LoadWordDisp(cu, rARM_SELF, Thread::ThinLockIdOffset().Int32Value(), r2);
// Is lock unheld on lock or held by us (==thread_id) on unlock?
OpRegRegImm(cu, kOpAnd, r3, r1,
@@ -532,7 +532,7 @@
NewLIR3(cu, kThumb2Bfc, r1, LW_HASH_STATE_SHIFT, LW_LOCK_OWNER_SHIFT - 1);
OpRegReg(cu, kOpSub, r1, r2);
OpIT(cu, kCondEq, "EE");
- StoreWordDisp(cu, r0, Object::MonitorOffset().Int32Value(), r3);
+ StoreWordDisp(cu, r0, mirror::Object::MonitorOffset().Int32Value(), r3);
// Go expensive route - UnlockObjectFromCode(obj);
LoadWordDisp(cu, rARM_SELF, ENTRYPOINT_OFFSET(pUnlockObjectFromCode), rARM_LR);
ClobberCalleeSave(cu);
diff --git a/src/compiler/codegen/arm/int_arm.cc b/src/compiler/codegen/arm/int_arm.cc
index e86f379..6a1178e 100644
--- a/src/compiler/codegen/arm/int_arm.cc
+++ b/src/compiler/codegen/arm/int_arm.cc
@@ -565,16 +565,16 @@
RegLocation rl_index, RegLocation rl_dest, int scale)
{
RegisterClass reg_class = oat_reg_class_by_size(size);
- int len_offset = Array::LengthOffset().Int32Value();
+ int len_offset = mirror::Array::LengthOffset().Int32Value();
int data_offset;
RegLocation rl_result;
rl_array = LoadValue(cu, rl_array, kCoreReg);
rl_index = LoadValue(cu, rl_index, kCoreReg);
if (rl_dest.wide) {
- data_offset = Array::DataOffset(sizeof(int64_t)).Int32Value();
+ data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Int32Value();
} else {
- data_offset = Array::DataOffset(sizeof(int32_t)).Int32Value();
+ data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Int32Value();
}
/* null object? */
@@ -637,13 +637,13 @@
RegLocation rl_index, RegLocation rl_src, int scale)
{
RegisterClass reg_class = oat_reg_class_by_size(size);
- int len_offset = Array::LengthOffset().Int32Value();
+ int len_offset = mirror::Array::LengthOffset().Int32Value();
int data_offset;
if (size == kLong || size == kDouble) {
- data_offset = Array::DataOffset(sizeof(int64_t)).Int32Value();
+ data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Int32Value();
} else {
- data_offset = Array::DataOffset(sizeof(int32_t)).Int32Value();
+ data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Int32Value();
}
rl_array = LoadValue(cu, rl_array, kCoreReg);
@@ -706,8 +706,8 @@
void ArmCodegen::GenArrayObjPut(CompilationUnit* cu, int opt_flags, RegLocation rl_array,
RegLocation rl_index, RegLocation rl_src, int scale)
{
- int len_offset = Array::LengthOffset().Int32Value();
- int data_offset = Array::DataOffset(sizeof(Object*)).Int32Value();
+ int len_offset = mirror::Array::LengthOffset().Int32Value();
+ int data_offset = mirror::Array::DataOffset(sizeof(mirror::Object*)).Int32Value();
FlushAllRegs(cu); // Use explicit registers
LockCallTemps(cu);
@@ -727,7 +727,7 @@
LIR* null_value_check = OpCmpImmBranch(cu, kCondEq, r_value, 0, NULL);
// Get the array's class.
- LoadWordDisp(cu, r_array, Object::ClassOffset().Int32Value(), r_array_class);
+ LoadWordDisp(cu, r_array, mirror::Object::ClassOffset().Int32Value(), r_array_class);
CallRuntimeHelperRegReg(cu, ENTRYPOINT_OFFSET(pCanPutArrayElementFromCode), r_value,
r_array_class, true);
// Redo LoadValues in case they didn't survive the call.
diff --git a/src/compiler/codegen/gen_common.cc b/src/compiler/codegen/gen_common.cc
index e1054db..acaad5b 100644
--- a/src/compiler/codegen/gen_common.cc
+++ b/src/compiler/codegen/gen_common.cc
@@ -330,7 +330,7 @@
SRegOffset(cu, rl_first.s_reg_low));
// Set up the target pointer
OpRegRegImm(cu, kOpAdd, r_dst, TargetReg(kRet0),
- Array::DataOffset(component_size).Int32Value());
+ mirror::Array::DataOffset(component_size).Int32Value());
// Set up the loop counter (known to be > 0)
LoadConstant(cu, r_idx, elems - 1);
// Generate the copy loop. Going backwards for convenience
@@ -342,14 +342,15 @@
OpDecAndBranch(cu, kCondGe, r_idx, target);
if (cu->instruction_set == kX86) {
// Restore the target pointer
- OpRegRegImm(cu, kOpAdd, TargetReg(kRet0), r_dst, -Array::DataOffset(component_size).Int32Value());
+ OpRegRegImm(cu, kOpAdd, TargetReg(kRet0), r_dst,
+ -mirror::Array::DataOffset(component_size).Int32Value());
}
} else if (!info->is_range) {
// TUNING: interleave
for (int i = 0; i < elems; i++) {
RegLocation rl_arg = LoadValue(cu, info->args[i], kCoreReg);
StoreBaseDisp(cu, TargetReg(kRet0),
- Array::DataOffset(component_size).Int32Value() +
+ mirror::Array::DataOffset(component_size).Int32Value() +
i * 4, rl_arg.low_reg, kWord);
// If the LoadValue caused a temp to be allocated, free it
if (IsTemp(cu, rl_arg.low_reg)) {
@@ -386,7 +387,7 @@
RegLocation rl_method = LoadCurrMethod(cu);
rBase = AllocTemp(cu);
LoadWordDisp(cu, rl_method.low_reg,
- AbstractMethod::DeclaringClassOffset().Int32Value(), rBase);
+ mirror::AbstractMethod::DeclaringClassOffset().Int32Value(), rBase);
if (IsTemp(cu, rl_method.low_reg)) {
FreeTemp(cu, rl_method.low_reg);
}
@@ -404,10 +405,10 @@
rBase = TargetReg(kArg0);
LockTemp(cu, rBase);
LoadWordDisp(cu, r_method,
- AbstractMethod::DexCacheInitializedStaticStorageOffset().Int32Value(),
+ mirror::AbstractMethod::DexCacheInitializedStaticStorageOffset().Int32Value(),
rBase);
LoadWordDisp(cu, rBase,
- Array::DataOffset(sizeof(Object*)).Int32Value() +
+ mirror::Array::DataOffset(sizeof(mirror::Object*)).Int32Value() +
sizeof(int32_t*) * ssb_index, rBase);
// rBase now points at appropriate static storage base (Class*)
// or NULL if not initialized. Check for NULL and call helper if NULL.
@@ -480,7 +481,7 @@
RegLocation rl_method = LoadCurrMethod(cu);
rBase = AllocTemp(cu);
LoadWordDisp(cu, rl_method.low_reg,
- AbstractMethod::DeclaringClassOffset().Int32Value(), rBase);
+ mirror::AbstractMethod::DeclaringClassOffset().Int32Value(), rBase);
} else {
// Medium path, static storage base in a different class which
// requires checks that the other class is initialized
@@ -495,10 +496,10 @@
rBase = TargetReg(kArg0);
LockTemp(cu, rBase);
LoadWordDisp(cu, r_method,
- AbstractMethod::DexCacheInitializedStaticStorageOffset().Int32Value(),
+ mirror::AbstractMethod::DexCacheInitializedStaticStorageOffset().Int32Value(),
rBase);
LoadWordDisp(cu, rBase,
- Array::DataOffset(sizeof(Object*)).Int32Value() +
+ mirror::Array::DataOffset(sizeof(mirror::Object*)).Int32Value() +
sizeof(int32_t*) * ssb_index, rBase);
// rBase now points at appropriate static storage base (Class*)
// or NULL if not initialized. Check for NULL and call helper if NULL.
@@ -619,7 +620,7 @@
OpRegCopy(cu, TargetReg(kArg0), v1);
if (target_x86) {
// x86 leaves the array pointer in v2, so load the array length that the handler expects
- OpRegMem(cu, kOpMov, TargetReg(kArg1), v2, Array::LengthOffset().Int32Value());
+ OpRegMem(cu, kOpMov, TargetReg(kArg1), v2, mirror::Array::LengthOffset().Int32Value());
} else {
OpRegCopy(cu, TargetReg(kArg1), v2);
}
@@ -629,7 +630,7 @@
OpRegCopy(cu, TargetReg(kArg2), v1);
if (target_x86) {
// x86 leaves the array pointer in v2; load the array length that the handler expects
- OpRegMem(cu, kOpMov, TargetReg(kArg1), v2, Array::LengthOffset().Int32Value());
+ OpRegMem(cu, kOpMov, TargetReg(kArg1), v2, mirror::Array::LengthOffset().Int32Value());
} else {
OpRegCopy(cu, TargetReg(kArg1), v2);
}
@@ -637,7 +638,7 @@
} else {
if (target_x86) {
// x86 leaves the array pointer in v2; load the array length that the handler expects
- OpRegMem(cu, kOpMov, TargetReg(kArg1), v2, Array::LengthOffset().Int32Value());
+ OpRegMem(cu, kOpMov, TargetReg(kArg1), v2, mirror::Array::LengthOffset().Int32Value());
} else {
OpRegCopy(cu, TargetReg(kArg1), v2);
}
@@ -799,10 +800,10 @@
} else {
// We're don't need access checks, load type from dex cache
int32_t dex_cache_offset =
- AbstractMethod::DexCacheResolvedTypesOffset().Int32Value();
+ mirror::AbstractMethod::DexCacheResolvedTypesOffset().Int32Value();
LoadWordDisp(cu, rl_method.low_reg, dex_cache_offset, res_reg);
int32_t offset_of_type =
- Array::DataOffset(sizeof(Class*)).Int32Value() + (sizeof(Class*)
+ mirror::Array::DataOffset(sizeof(mirror::Class*)).Int32Value() + (sizeof(mirror::Class*)
* type_idx);
LoadWordDisp(cu, res_reg, offset_of_type, rl_result.low_reg);
if (!cu->compiler->CanAssumeTypeIsPresentInDexCache(*cu->dex_file,
@@ -844,8 +845,8 @@
void Codegen::GenConstString(CompilationUnit* cu, uint32_t string_idx, RegLocation rl_dest)
{
/* NOTE: Most strings should be available at compile time */
- int32_t offset_of_string = Array::DataOffset(sizeof(String*)).Int32Value() +
- (sizeof(String*) * string_idx);
+ int32_t offset_of_string = mirror::Array::DataOffset(sizeof(mirror::String*)).Int32Value() +
+ (sizeof(mirror::String*) * string_idx);
if (!cu->compiler->CanAssumeStringIsPresentInDexCache(
*cu->dex_file, string_idx) || SLOW_STRING_PATH) {
// slow path, resolve string if not in dex cache
@@ -853,7 +854,7 @@
LockCallTemps(cu); // Using explicit registers
LoadCurrMethodDirect(cu, TargetReg(kArg2));
LoadWordDisp(cu, TargetReg(kArg2),
- AbstractMethod::DexCacheStringsOffset().Int32Value(), TargetReg(kArg0));
+ mirror::AbstractMethod::DexCacheStringsOffset().Int32Value(), TargetReg(kArg0));
// Might call out to helper, which will return resolved string in kRet0
int r_tgt = CallHelperSetup(cu, ENTRYPOINT_OFFSET(pResolveStringFromCode));
LoadWordDisp(cu, TargetReg(kArg0), offset_of_string, TargetReg(kRet0));
@@ -888,7 +889,7 @@
int res_reg = AllocTemp(cu);
RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
LoadWordDisp(cu, rl_method.low_reg,
- AbstractMethod::DexCacheStringsOffset().Int32Value(), res_reg);
+ mirror::AbstractMethod::DexCacheStringsOffset().Int32Value(), res_reg);
LoadWordDisp(cu, res_reg, offset_of_string, rl_result.low_reg);
StoreValue(cu, rl_dest, rl_result);
}
@@ -942,9 +943,9 @@
// Load dex cache entry into class_reg (kArg2)
LoadValueDirectFixed(cu, rl_src, TargetReg(kArg0)); // kArg0 <= ref
LoadWordDisp(cu, TargetReg(kArg1),
- AbstractMethod::DexCacheResolvedTypesOffset().Int32Value(), class_reg);
+ mirror::AbstractMethod::DexCacheResolvedTypesOffset().Int32Value(), class_reg);
int32_t offset_of_type =
- Array::DataOffset(sizeof(Class*)).Int32Value() + (sizeof(Class*)
+ mirror::Array::DataOffset(sizeof(mirror::Class*)).Int32Value() + (sizeof(mirror::Class*)
* type_idx);
LoadWordDisp(cu, class_reg, offset_of_type, class_reg);
if (!cu->compiler->CanAssumeTypeIsPresentInDexCache(
@@ -968,8 +969,8 @@
}
LIR* branch1 = OpCmpImmBranch(cu, kCondEq, TargetReg(kArg0), 0, NULL);
/* load object->klass_ */
- DCHECK_EQ(Object::ClassOffset().Int32Value(), 0);
- LoadWordDisp(cu, TargetReg(kArg0), Object::ClassOffset().Int32Value(), TargetReg(kArg1));
+ DCHECK_EQ(mirror::Object::ClassOffset().Int32Value(), 0);
+ LoadWordDisp(cu, TargetReg(kArg0), mirror::Object::ClassOffset().Int32Value(), TargetReg(kArg1));
/* kArg0 is ref, kArg1 is ref->klass_, kArg2 is class */
LIR* call_inst;
LIR* branchover = NULL;
@@ -1026,10 +1027,10 @@
} else {
// Load dex cache entry into class_reg (kArg2)
LoadWordDisp(cu, TargetReg(kArg1),
- AbstractMethod::DexCacheResolvedTypesOffset().Int32Value(), class_reg);
+ mirror::AbstractMethod::DexCacheResolvedTypesOffset().Int32Value(), class_reg);
int32_t offset_of_type =
- Array::DataOffset(sizeof(Class*)).Int32Value() +
- (sizeof(Class*) * type_idx);
+ mirror::Array::DataOffset(sizeof(mirror::Class*)).Int32Value() +
+ (sizeof(mirror::Class*) * type_idx);
LoadWordDisp(cu, class_reg, offset_of_type, class_reg);
if (!cu->compiler->CanAssumeTypeIsPresentInDexCache(
*cu->dex_file, type_idx)) {
@@ -1051,8 +1052,8 @@
/* Null is OK - continue */
LIR* branch1 = OpCmpImmBranch(cu, kCondEq, TargetReg(kArg0), 0, NULL);
/* load object->klass_ */
- DCHECK_EQ(Object::ClassOffset().Int32Value(), 0);
- LoadWordDisp(cu, TargetReg(kArg0), Object::ClassOffset().Int32Value(), TargetReg(kArg1));
+ DCHECK_EQ(mirror::Object::ClassOffset().Int32Value(), 0);
+ LoadWordDisp(cu, TargetReg(kArg0), mirror::Object::ClassOffset().Int32Value(), TargetReg(kArg1));
/* kArg1 now contains object->klass_ */
LIR* branch2;
if (cu->instruction_set == kThumb2) {
diff --git a/src/compiler/codegen/gen_invoke.cc b/src/compiler/codegen/gen_invoke.cc
index fe60aff..78425c4 100644
--- a/src/compiler/codegen/gen_invoke.cc
+++ b/src/compiler/codegen/gen_invoke.cc
@@ -365,7 +365,7 @@
break;
case 1: // Get method->dex_cache_resolved_methods_
cg->LoadWordDisp(cu, cg->TargetReg(kArg0),
- AbstractMethod::DexCacheResolvedMethodsOffset().Int32Value(), cg->TargetReg(kArg0));
+ mirror::AbstractMethod::DexCacheResolvedMethodsOffset().Int32Value(), cg->TargetReg(kArg0));
// Set up direct code if known.
if (direct_code != 0) {
if (direct_code != static_cast<unsigned int>(-1)) {
@@ -384,13 +384,14 @@
break;
case 2: // Grab target method*
cg->LoadWordDisp(cu, cg->TargetReg(kArg0),
- Array::DataOffset(sizeof(Object*)).Int32Value() + dex_idx * 4,
+ mirror::Array::DataOffset(sizeof(mirror::Object*)).Int32Value() + dex_idx * 4,
cg-> TargetReg(kArg0));
break;
case 3: // Grab the code from the method*
if (cu->instruction_set != kX86) {
if (direct_code == 0) {
- cg->LoadWordDisp(cu, cg->TargetReg(kArg0), AbstractMethod::GetCodeOffset().Int32Value(),
+ cg->LoadWordDisp(cu, cg->TargetReg(kArg0),
+ mirror::AbstractMethod::GetCodeOffset().Int32Value(),
cg->TargetReg(kInvokeTgt));
}
break;
@@ -428,20 +429,22 @@
case 1: // Is "this" null? [use kArg1]
cg->GenNullCheck(cu, info->args[0].s_reg_low, cg->TargetReg(kArg1), info->opt_flags);
// get this->klass_ [use kArg1, set kInvokeTgt]
- cg->LoadWordDisp(cu, cg->TargetReg(kArg1), Object::ClassOffset().Int32Value(),
+ cg->LoadWordDisp(cu, cg->TargetReg(kArg1), mirror::Object::ClassOffset().Int32Value(),
cg->TargetReg(kInvokeTgt));
break;
case 2: // Get this->klass_->vtable [usr kInvokeTgt, set kInvokeTgt]
- cg->LoadWordDisp(cu, cg->TargetReg(kInvokeTgt), Class::VTableOffset().Int32Value(),
+ cg->LoadWordDisp(cu, cg->TargetReg(kInvokeTgt), mirror::Class::VTableOffset().Int32Value(),
cg->TargetReg(kInvokeTgt));
break;
case 3: // Get target method [use kInvokeTgt, set kArg0]
cg->LoadWordDisp(cu, cg->TargetReg(kInvokeTgt), (method_idx * 4) +
- Array::DataOffset(sizeof(Object*)).Int32Value(), cg->TargetReg(kArg0));
+ mirror::Array::DataOffset(sizeof(mirror::Object*)).Int32Value(),
+ cg->TargetReg(kArg0));
break;
case 4: // Get the compiled code address [uses kArg0, sets kInvokeTgt]
if (cu->instruction_set != kX86) {
- cg->LoadWordDisp(cu, cg->TargetReg(kArg0), AbstractMethod::GetCodeOffset().Int32Value(),
+ cg->LoadWordDisp(cu, cg->TargetReg(kArg0),
+ mirror::AbstractMethod::GetCodeOffset().Int32Value(),
cg->TargetReg(kInvokeTgt));
break;
}
@@ -503,12 +506,12 @@
break;
case 1: // Get method->dex_cache_resolved_methods_ [set/use kArg0]
cg->LoadWordDisp(cu, cg->TargetReg(kArg0),
- AbstractMethod::DexCacheResolvedMethodsOffset().Int32Value(),
+ mirror::AbstractMethod::DexCacheResolvedMethodsOffset().Int32Value(),
cg->TargetReg(kArg0));
break;
case 2: // Grab target method* [set/use kArg0]
cg->LoadWordDisp(cu, cg->TargetReg(kArg0),
- Array::DataOffset(sizeof(Object*)).Int32Value() + dex_idx * 4,
+ mirror::Array::DataOffset(sizeof(mirror::Object*)).Int32Value() + dex_idx * 4,
cg->TargetReg(kArg0));
break;
default:
@@ -837,13 +840,13 @@
return false;
}
// Location of reference to data array
- int value_offset = String::ValueOffset().Int32Value();
+ int value_offset = mirror::String::ValueOffset().Int32Value();
// Location of count
- int count_offset = String::CountOffset().Int32Value();
+ int count_offset = mirror::String::CountOffset().Int32Value();
// Starting offset within data array
- int offset_offset = String::OffsetOffset().Int32Value();
+ int offset_offset = mirror::String::OffsetOffset().Int32Value();
// Start of char data with array_
- int data_offset = Array::DataOffset(sizeof(uint16_t)).Int32Value();
+ int data_offset = mirror::Array::DataOffset(sizeof(uint16_t)).Int32Value();
RegLocation rl_obj = info->args[0];
RegLocation rl_idx = info->args[1];
@@ -921,7 +924,7 @@
RegLocation rl_dest = InlineTarget(cu, info);
RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
GenNullCheck(cu, rl_obj.s_reg_low, rl_obj.low_reg, info->opt_flags);
- LoadWordDisp(cu, rl_obj.low_reg, String::CountOffset().Int32Value(),
+ LoadWordDisp(cu, rl_obj.low_reg, mirror::String::CountOffset().Int32Value(),
rl_result.low_reg);
if (is_empty) {
// dst = (dst == 0);
@@ -1284,7 +1287,7 @@
} else {
if (fast_path && info->type != kInterface) {
call_inst = OpMem(cu, kOpBlx, TargetReg(kArg0),
- AbstractMethod::GetCodeOffset().Int32Value());
+ mirror::AbstractMethod::GetCodeOffset().Int32Value());
} else {
int trampoline = 0;
switch (info->type) {
diff --git a/src/compiler/codegen/mips/int_mips.cc b/src/compiler/codegen/mips/int_mips.cc
index e2a5a02..86f0527 100644
--- a/src/compiler/codegen/mips/int_mips.cc
+++ b/src/compiler/codegen/mips/int_mips.cc
@@ -439,16 +439,16 @@
RegLocation rl_index, RegLocation rl_dest, int scale)
{
RegisterClass reg_class = oat_reg_class_by_size(size);
- int len_offset = Array::LengthOffset().Int32Value();
+ int len_offset = mirror::Array::LengthOffset().Int32Value();
int data_offset;
RegLocation rl_result;
rl_array = LoadValue(cu, rl_array, kCoreReg);
rl_index = LoadValue(cu, rl_index, kCoreReg);
if (size == kLong || size == kDouble) {
- data_offset = Array::DataOffset(sizeof(int64_t)).Int32Value();
+ data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Int32Value();
} else {
- data_offset = Array::DataOffset(sizeof(int32_t)).Int32Value();
+ data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Int32Value();
}
/* null object? */
@@ -511,13 +511,13 @@
RegLocation rl_index, RegLocation rl_src, int scale)
{
RegisterClass reg_class = oat_reg_class_by_size(size);
- int len_offset = Array::LengthOffset().Int32Value();
+ int len_offset = mirror::Array::LengthOffset().Int32Value();
int data_offset;
if (size == kLong || size == kDouble) {
- data_offset = Array::DataOffset(sizeof(int64_t)).Int32Value();
+ data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Int32Value();
} else {
- data_offset = Array::DataOffset(sizeof(int32_t)).Int32Value();
+ data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Int32Value();
}
rl_array = LoadValue(cu, rl_array, kCoreReg);
@@ -583,8 +583,8 @@
void MipsCodegen::GenArrayObjPut(CompilationUnit* cu, int opt_flags, RegLocation rl_array,
RegLocation rl_index, RegLocation rl_src, int scale)
{
- int len_offset = Array::LengthOffset().Int32Value();
- int data_offset = Array::DataOffset(sizeof(Object*)).Int32Value();
+ int len_offset = mirror::Array::LengthOffset().Int32Value();
+ int data_offset = mirror::Array::DataOffset(sizeof(mirror::Object*)).Int32Value();
FlushAllRegs(cu); // Use explicit registers
LockCallTemps(cu);
@@ -604,7 +604,7 @@
LIR* null_value_check = OpCmpImmBranch(cu, kCondEq, r_value, 0, NULL);
// Get the array's class.
- LoadWordDisp(cu, r_array, Object::ClassOffset().Int32Value(), r_array_class);
+ LoadWordDisp(cu, r_array, mirror::Object::ClassOffset().Int32Value(), r_array_class);
CallRuntimeHelperRegReg(cu, ENTRYPOINT_OFFSET(pCanPutArrayElementFromCode), r_value,
r_array_class, true);
// Redo LoadValues in case they didn't survive the call.
diff --git a/src/compiler/codegen/mir_to_gbc.cc b/src/compiler/codegen/mir_to_gbc.cc
index e38977a..2657b79 100644
--- a/src/compiler/codegen/mir_to_gbc.cc
+++ b/src/compiler/codegen/mir_to_gbc.cc
@@ -2684,7 +2684,7 @@
cg->GenNullCheck(cu, rl_src.s_reg_low, rl_src.low_reg, opt_flags->getZExtValue());
RegLocation rl_dest = GetLoc(cu, call_inst);
RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
- int len_offset = Array::LengthOffset().Int32Value();
+ int len_offset = mirror::Array::LengthOffset().Int32Value();
cg->LoadWordDisp(cu, rl_src.low_reg, len_offset, rl_result.low_reg);
cg->StoreValue(cu, rl_dest, rl_result);
}
diff --git a/src/compiler/codegen/mir_to_lir.cc b/src/compiler/codegen/mir_to_lir.cc
index 2bc0f86..77d581f 100644
--- a/src/compiler/codegen/mir_to_lir.cc
+++ b/src/compiler/codegen/mir_to_lir.cc
@@ -210,7 +210,7 @@
case Instruction::ARRAY_LENGTH:
int len_offset;
- len_offset = Array::LengthOffset().Int32Value();
+ len_offset = mirror::Array::LengthOffset().Int32Value();
rl_src[0] = cg->LoadValue(cu, rl_src[0], kCoreReg);
cg->GenNullCheck(cu, rl_src[0].s_reg_low, rl_src[0].low_reg, opt_flags);
rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
diff --git a/src/compiler/codegen/x86/call_x86.cc b/src/compiler/codegen/x86/call_x86.cc
index 727c5e8..f9b25c8 100644
--- a/src/compiler/codegen/x86/call_x86.cc
+++ b/src/compiler/codegen/x86/call_x86.cc
@@ -163,7 +163,7 @@
NewLIR2(cu, kX86Mov32RT, rDX, Thread::ThinLockIdOffset().Int32Value());
NewLIR2(cu, kX86Sal32RI, rDX, LW_LOCK_OWNER_SHIFT);
NewLIR2(cu, kX86Xor32RR, rAX, rAX);
- NewLIR3(cu, kX86LockCmpxchgMR, rCX, Object::MonitorOffset().Int32Value(), rDX);
+ NewLIR3(cu, kX86LockCmpxchgMR, rCX, mirror::Object::MonitorOffset().Int32Value(), rDX);
LIR* branch = NewLIR2(cu, kX86Jcc8, 0, kX86CondEq);
// If lock is held, go the expensive route - artLockObjectFromCode(self, obj);
CallRuntimeHelperReg(cu, ENTRYPOINT_OFFSET(pLockObjectFromCode), rCX, true);
@@ -180,10 +180,10 @@
// TODO: clear hash state?
NewLIR2(cu, kX86Mov32RT, rDX, Thread::ThinLockIdOffset().Int32Value());
NewLIR2(cu, kX86Sal32RI, rDX, LW_LOCK_OWNER_SHIFT);
- NewLIR3(cu, kX86Mov32RM, rCX, rAX, Object::MonitorOffset().Int32Value());
+ NewLIR3(cu, kX86Mov32RM, rCX, rAX, mirror::Object::MonitorOffset().Int32Value());
OpRegReg(cu, kOpSub, rCX, rDX);
LIR* branch = NewLIR2(cu, kX86Jcc8, 0, kX86CondNe);
- NewLIR3(cu, kX86Mov32MR, rAX, Object::MonitorOffset().Int32Value(), rCX);
+ NewLIR3(cu, kX86Mov32MR, rAX, mirror::Object::MonitorOffset().Int32Value(), rCX);
LIR* branch2 = NewLIR1(cu, kX86Jmp8, 0);
branch->target = NewLIR0(cu, kPseudoTargetLabel);
// Otherwise, go the expensive route - UnlockObjectFromCode(obj);
diff --git a/src/compiler/codegen/x86/int_x86.cc b/src/compiler/codegen/x86/int_x86.cc
index 0f1fc53..f2d023c 100644
--- a/src/compiler/codegen/x86/int_x86.cc
+++ b/src/compiler/codegen/x86/int_x86.cc
@@ -446,16 +446,16 @@
RegLocation rl_index, RegLocation rl_dest, int scale)
{
RegisterClass reg_class = oat_reg_class_by_size(size);
- int len_offset = Array::LengthOffset().Int32Value();
+ int len_offset = mirror::Array::LengthOffset().Int32Value();
int data_offset;
RegLocation rl_result;
rl_array = LoadValue(cu, rl_array, kCoreReg);
rl_index = LoadValue(cu, rl_index, kCoreReg);
if (size == kLong || size == kDouble) {
- data_offset = Array::DataOffset(sizeof(int64_t)).Int32Value();
+ data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Int32Value();
} else {
- data_offset = Array::DataOffset(sizeof(int32_t)).Int32Value();
+ data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Int32Value();
}
/* null object? */
@@ -494,13 +494,13 @@
RegLocation rl_index, RegLocation rl_src, int scale)
{
RegisterClass reg_class = oat_reg_class_by_size(size);
- int len_offset = Array::LengthOffset().Int32Value();
+ int len_offset = mirror::Array::LengthOffset().Int32Value();
int data_offset;
if (size == kLong || size == kDouble) {
- data_offset = Array::DataOffset(sizeof(int64_t)).Int32Value();
+ data_offset = mirror::Array::DataOffset(sizeof(int64_t)).Int32Value();
} else {
- data_offset = Array::DataOffset(sizeof(int32_t)).Int32Value();
+ data_offset = mirror::Array::DataOffset(sizeof(int32_t)).Int32Value();
}
rl_array = LoadValue(cu, rl_array, kCoreReg);
@@ -537,8 +537,8 @@
void X86Codegen::GenArrayObjPut(CompilationUnit* cu, int opt_flags, RegLocation rl_array,
RegLocation rl_index, RegLocation rl_src, int scale)
{
- int len_offset = Array::LengthOffset().Int32Value();
- int data_offset = Array::DataOffset(sizeof(Object*)).Int32Value();
+ int len_offset = mirror::Array::LengthOffset().Int32Value();
+ int data_offset = mirror::Array::DataOffset(sizeof(mirror::Object*)).Int32Value();
FlushAllRegs(cu); // Use explicit registers
LockCallTemps(cu);
@@ -558,7 +558,7 @@
LIR* null_value_check = OpCmpImmBranch(cu, kCondEq, r_value, 0, NULL);
// Get the array's class.
- LoadWordDisp(cu, r_array, Object::ClassOffset().Int32Value(), r_array_class);
+ LoadWordDisp(cu, r_array, mirror::Object::ClassOffset().Int32Value(), r_array_class);
CallRuntimeHelperRegReg(cu, ENTRYPOINT_OFFSET(pCanPutArrayElementFromCode), r_value,
r_array_class, true);
// Redo LoadValues in case they didn't survive the call.
diff --git a/src/compiler/compiler_internals.h b/src/compiler/compiler_internals.h
index 1379a3b..746999d 100644
--- a/src/compiler/compiler_internals.h
+++ b/src/compiler/compiler_internals.h
@@ -28,11 +28,10 @@
#include "compiler.h"
#include "compiler_ir.h"
#include "compiler_utility.h"
-#include "dex_cache.h"
#include "frontend.h"
#include "gc/card_table.h"
+#include "mirror/dex_cache.h"
#include "monitor.h"
-#include "object.h"
#include "ralloc.h"
#include "thread.h"
#include "utils.h"
diff --git a/src/compiler/frontend.cc b/src/compiler/frontend.cc
index 31423ef..6ccbc07 100644
--- a/src/compiler/frontend.cc
+++ b/src/compiler/frontend.cc
@@ -19,7 +19,7 @@
#include "dataflow.h"
#include "ssa_transformation.h"
#include "leb128.h"
-#include "object.h"
+#include "mirror/object.h"
#include "runtime.h"
#include "codegen/codegen_util.h"
#include "codegen/mir_to_gbc.h"
diff --git a/src/compiler_llvm/compiler_llvm.h b/src/compiler_llvm/compiler_llvm.h
index 9aa9791..bb14c49 100644
--- a/src/compiler_llvm/compiler_llvm.h
+++ b/src/compiler_llvm/compiler_llvm.h
@@ -21,7 +21,7 @@
#include "compiler.h"
#include "dex_file.h"
#include "instruction_set.h"
-#include "object.h"
+#include "mirror/object.h"
#include "procedure_linkage_table.h"
#include <UniquePtr.h>
@@ -31,13 +31,15 @@
#include <vector>
namespace art {
- class ClassLoader;
class CompiledInvokeStub;
class CompiledMethod;
class Compiler;
class OatCompilationUnit;
- class AbstractMethod;
-}
+ namespace mirror {
+ class AbstractMethod;
+ class ClassLoader;
+ } // namespace mirror
+} // namespace art
namespace llvm {
@@ -47,7 +49,7 @@
class PointerType;
class StructType;
class Type;
-}
+} // namespace llvm
namespace art {
diff --git a/src/compiler_llvm/gbc_expander.cc b/src/compiler_llvm/gbc_expander.cc
index a7970d5..0348874 100644
--- a/src/compiler_llvm/gbc_expander.cc
+++ b/src/compiler_llvm/gbc_expander.cc
@@ -19,8 +19,8 @@
#include "compiler.h"
#include "greenland/intrinsic_helper.h"
+#include "mirror/object.h"
#include "oat_compilation_unit.h"
-#include "object.h"
#include "thread.h"
#include "verifier/method_verifier.h"
diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc
index da55d94..e81afed 100644
--- a/src/compiler_llvm/jni_compiler.cc
+++ b/src/compiler_llvm/jni_compiler.cc
@@ -23,8 +23,8 @@
#include "compiler.h"
#include "compiler_llvm.h"
#include "ir_builder.h"
+#include "mirror/object.h"
#include "oat_compilation_unit.h"
-#include "object.h"
#include "runtime.h"
#include "runtime_support_func.h"
#include "utils_llvm.h"
diff --git a/src/compiler_llvm/jni_compiler.h b/src/compiler_llvm/jni_compiler.h
index c428775..0731e92 100644
--- a/src/compiler_llvm/jni_compiler.h
+++ b/src/compiler_llvm/jni_compiler.h
@@ -21,14 +21,16 @@
namespace art {
class ClassLinker;
- class ClassLoader;
class CompiledMethod;
class Compiler;
- class DexCache;
class DexFile;
- class AbstractMethod;
class OatCompilationUnit;
-}
+ namespace mirror {
+ class AbstractMethod;
+ class ClassLoader;
+ class DexCache;
+ } // namespace mirror
+} // namespace art
namespace llvm {
class AllocaInst;
@@ -39,7 +41,7 @@
class Module;
class Type;
class Value;
-}
+} // namespace llvm
namespace art {
namespace compiler_llvm {
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index ccec7e9..bc3fb92 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -25,8 +25,8 @@
#include "dalvik_reg.h"
#include "greenland/inferred_reg_category_map.h"
#include "ir_builder.h"
+#include "mirror/object.h"
#include "oat_compilation_unit.h"
-#include "object.h"
#include "object_utils.h"
#include "runtime_support_func.h"
#include "runtime_support_llvm.h"
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index f67866a..dd9d182 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -34,17 +34,20 @@
namespace art {
class ClassLinker;
- class ClassLoader;
class CompiledMethod;
class Compiler;
- class DexCache;
- class Field;
class OatCompilationUnit;
+ namespace mirror {
+ class ClassLoader;
+ class DexCache;
+ class Field;
+ } // namespace mirror
+
namespace greenland {
class InferredRegCategoryMap;
- }
-}
+ } // namespace greenland
+} // namespace art
namespace llvm {
@@ -55,7 +58,7 @@
class LLVMContext;
class Module;
class Type;
-}
+} // namespace llvm
namespace art {
diff --git a/src/compiler_llvm/runtime_support_builder.cc b/src/compiler_llvm/runtime_support_builder.cc
index 169f8e8..36b5fa1 100644
--- a/src/compiler_llvm/runtime_support_builder.cc
+++ b/src/compiler_llvm/runtime_support_builder.cc
@@ -19,7 +19,7 @@
#include "gc/card_table.h"
#include "ir_builder.h"
#include "monitor.h"
-#include "object.h"
+#include "mirror/object.h"
#include "thread.h"
#include <llvm/DerivedTypes.h>
@@ -179,7 +179,7 @@
kTBAARuntimeInfo);
Value* monitor =
irb_.LoadFromObjectOffset(object,
- Object::MonitorOffset().Int32Value(),
+ mirror::Object::MonitorOffset().Int32Value(),
irb_.getJIntTy(),
kTBAARuntimeInfo);
@@ -199,7 +199,7 @@
irb_.SetInsertPoint(bb_fast);
// Set all bits to zero (except hash state)
irb_.StoreToObjectOffset(object,
- Object::MonitorOffset().Int32Value(),
+ mirror::Object::MonitorOffset().Int32Value(),
hash_state,
kTBAARuntimeInfo);
irb_.CreateBr(bb_cont);
diff --git a/src/compiler_llvm/runtime_support_builder_thumb2.cc b/src/compiler_llvm/runtime_support_builder_thumb2.cc
index 3299afe..c18ae83 100644
--- a/src/compiler_llvm/runtime_support_builder_thumb2.cc
+++ b/src/compiler_llvm/runtime_support_builder_thumb2.cc
@@ -17,8 +17,8 @@
#include "runtime_support_builder_thumb2.h"
#include "ir_builder.h"
+#include "mirror/object.h"
#include "monitor.h"
-#include "object.h"
#include "thread.h"
#include "utils_llvm.h"
diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc
index d3552e9..8de90ff 100644
--- a/src/compiler_llvm/runtime_support_llvm.cc
+++ b/src/compiler_llvm/runtime_support_llvm.cc
@@ -22,8 +22,8 @@
#include "compiler_runtime_func_list.h"
#include "dex_file.h"
#include "dex_instruction.h"
+#include "mirror/object.h"
#include "nth_caller_visitor.h"
-#include "object.h"
#include "object_utils.h"
#include "reflection.h"
#include "runtime_support.h"
@@ -60,7 +60,7 @@
return NULL;
}
-void art_lock_object_from_code(Object* obj, Thread* thread)
+void art_lock_object_from_code(mirror::Object* obj, Thread* thread)
EXCLUSIVE_LOCK_FUNCTION(monitor_lock_) {
DCHECK(obj != NULL); // Assumed to have been checked before entry
obj->MonitorEnter(thread); // May block
@@ -69,7 +69,7 @@
DCHECK(!thread->IsExceptionPending());
}
-void art_unlock_object_from_code(Object* obj, Thread* thread)
+void art_unlock_object_from_code(mirror::Object* obj, Thread* thread)
UNLOCK_FUNCTION(monitor_lock_) {
DCHECK(obj != NULL); // Assumed to have been checked before entry
// MonitorExit may throw exception
@@ -82,7 +82,7 @@
}
ShadowFrame* art_push_shadow_frame_from_code(Thread* thread, ShadowFrame* new_shadow_frame,
- AbstractMethod* method, uint32_t num_vregs) {
+ mirror::AbstractMethod* method, uint32_t num_vregs) {
ShadowFrame* old_frame = thread->PushShadowFrame(new_shadow_frame);
new_shadow_frame->SetMethod(method);
new_shadow_frame->SetNumberOfVRegs(num_vregs);
@@ -120,13 +120,13 @@
void art_throw_no_such_method_from_code(int32_t method_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// We need the calling method as context for the method_idx.
- AbstractMethod* method = Thread::Current()->GetCurrentMethod();
+ mirror::AbstractMethod* method = Thread::Current()->GetCurrentMethod();
ThrowNoSuchMethodError(method_idx, method);
}
void art_throw_null_pointer_exception_from_code(uint32_t dex_pc)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* throw_method =
+ mirror::AbstractMethod* throw_method =
Thread::Current()->GetManagedStack()->GetTopShadowFrame()->GetMethod();
ThrowNullPointerExceptionFromDexPC(throw_method, dex_pc);
}
@@ -135,21 +135,21 @@
ThrowStackOverflowError(Thread::Current());
}
-void art_throw_exception_from_code(Object* exception) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Thread::Current()->DeliverException(static_cast<Throwable*>(exception));
+void art_throw_exception_from_code(mirror::Object* exception) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ Thread::Current()->DeliverException(static_cast<mirror::Throwable*>(exception));
}
void* art_get_and_clear_exception(Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(self->IsExceptionPending());
- Throwable* exception = self->GetException();
+ mirror::Throwable* exception = self->GetException();
self->ClearException();
return exception;
}
-int32_t art_find_catch_block_from_code(AbstractMethod* current_method, uint32_t ti_offset)
+int32_t art_find_catch_block_from_code(mirror::AbstractMethod* current_method, uint32_t ti_offset)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Class* exception_type = Thread::Current()->GetException()->GetClass();
+ mirror::Class* exception_type = Thread::Current()->GetException()->GetClass();
MethodHelper mh(current_method);
const DexFile::CodeItem* code_item = mh.GetCodeItem();
DCHECK_LT(ti_offset, code_item->tries_size_);
@@ -164,7 +164,7 @@
return iter_index;
}
// Does this catch exception type apply?
- Class* iter_exception_type = mh.GetDexCacheResolvedType(iter_type_idx);
+ mirror::Class* iter_exception_type = mh.GetDexCacheResolvedType(iter_type_idx);
if (iter_exception_type == NULL) {
// The verifier should take care of resolving all exception classes early
LOG(WARNING) << "Unresolved exception class when finding catch block: "
@@ -183,57 +183,57 @@
// Object Space
//----------------------------------------------------------------------------
-Object* art_alloc_object_from_code(uint32_t type_idx,
- AbstractMethod* referrer,
+mirror::Object* art_alloc_object_from_code(uint32_t type_idx,
+ mirror::AbstractMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return AllocObjectFromCode(type_idx, referrer, thread, false);
}
-Object* art_alloc_object_from_code_with_access_check(uint32_t type_idx,
- AbstractMethod* referrer,
+mirror::Object* art_alloc_object_from_code_with_access_check(uint32_t type_idx,
+ mirror::AbstractMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return AllocObjectFromCode(type_idx, referrer, thread, true);
}
-Object* art_alloc_array_from_code(uint32_t type_idx,
- AbstractMethod* referrer,
+mirror::Object* art_alloc_array_from_code(uint32_t type_idx,
+ mirror::AbstractMethod* referrer,
uint32_t length,
Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return AllocArrayFromCode(type_idx, referrer, length, self, false);
}
-Object* art_alloc_array_from_code_with_access_check(uint32_t type_idx,
- AbstractMethod* referrer,
+mirror::Object* art_alloc_array_from_code_with_access_check(uint32_t type_idx,
+ mirror::AbstractMethod* referrer,
uint32_t length,
Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return AllocArrayFromCode(type_idx, referrer, length, self, true);
}
-Object* art_check_and_alloc_array_from_code(uint32_t type_idx,
- AbstractMethod* referrer,
+mirror::Object* art_check_and_alloc_array_from_code(uint32_t type_idx,
+ mirror::AbstractMethod* referrer,
uint32_t length,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return CheckAndAllocArrayFromCode(type_idx, referrer, length, thread, false);
}
-Object* art_check_and_alloc_array_from_code_with_access_check(uint32_t type_idx,
- AbstractMethod* referrer,
+mirror::Object* art_check_and_alloc_array_from_code_with_access_check(uint32_t type_idx,
+ mirror::AbstractMethod* referrer,
uint32_t length,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return CheckAndAllocArrayFromCode(type_idx, referrer, length, thread, true);
}
-static AbstractMethod* FindMethodHelper(uint32_t method_idx, Object* this_object,
- AbstractMethod* caller_method, bool access_check,
+static mirror::AbstractMethod* FindMethodHelper(uint32_t method_idx, mirror::Object* this_object,
+ mirror::AbstractMethod* caller_method, bool access_check,
InvokeType type, Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method = FindMethodFast(method_idx, this_object, caller_method, access_check, type);
+ mirror::AbstractMethod* method = FindMethodFast(method_idx, this_object, caller_method, access_check, type);
if (UNLIKELY(method == NULL)) {
method = FindMethodFromCode(method_idx, this_object, caller_method,
thread, access_check, type);
@@ -254,71 +254,71 @@
return method;
}
-Object* art_find_static_method_from_code_with_access_check(uint32_t method_idx,
- Object* this_object,
- AbstractMethod* referrer,
+mirror::Object* art_find_static_method_from_code_with_access_check(uint32_t method_idx,
+ mirror::Object* this_object,
+ mirror::AbstractMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return FindMethodHelper(method_idx, this_object, referrer, true, kStatic, thread);
}
-Object* art_find_direct_method_from_code_with_access_check(uint32_t method_idx,
- Object* this_object,
- AbstractMethod* referrer,
+mirror::Object* art_find_direct_method_from_code_with_access_check(uint32_t method_idx,
+ mirror::Object* this_object,
+ mirror::AbstractMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return FindMethodHelper(method_idx, this_object, referrer, true, kDirect, thread);
}
-Object* art_find_virtual_method_from_code_with_access_check(uint32_t method_idx,
- Object* this_object,
- AbstractMethod* referrer,
+mirror::Object* art_find_virtual_method_from_code_with_access_check(uint32_t method_idx,
+ mirror::Object* this_object,
+ mirror::AbstractMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return FindMethodHelper(method_idx, this_object, referrer, true, kVirtual, thread);
}
-Object* art_find_super_method_from_code_with_access_check(uint32_t method_idx,
- Object* this_object,
- AbstractMethod* referrer,
+mirror::Object* art_find_super_method_from_code_with_access_check(uint32_t method_idx,
+ mirror::Object* this_object,
+ mirror::AbstractMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return FindMethodHelper(method_idx, this_object, referrer, true, kSuper, thread);
}
-Object*
+mirror::Object*
art_find_interface_method_from_code_with_access_check(uint32_t method_idx,
- Object* this_object,
- AbstractMethod* referrer,
+ mirror::Object* this_object,
+ mirror::AbstractMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return FindMethodHelper(method_idx, this_object, referrer, true, kInterface, thread);
}
-Object* art_find_interface_method_from_code(uint32_t method_idx,
- Object* this_object,
- AbstractMethod* referrer,
+mirror::Object* art_find_interface_method_from_code(uint32_t method_idx,
+ mirror::Object* this_object,
+ mirror::AbstractMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return FindMethodHelper(method_idx, this_object, referrer, false, kInterface, thread);
}
-Object* art_initialize_static_storage_from_code(uint32_t type_idx,
- AbstractMethod* referrer,
+mirror::Object* art_initialize_static_storage_from_code(uint32_t type_idx,
+ mirror::AbstractMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return ResolveVerifyAndClinit(type_idx, referrer, thread, true, false);
}
-Object* art_initialize_type_from_code(uint32_t type_idx,
- AbstractMethod* referrer,
+mirror::Object* art_initialize_type_from_code(uint32_t type_idx,
+ mirror::AbstractMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return ResolveVerifyAndClinit(type_idx, referrer, thread, false, false);
}
-Object* art_initialize_type_and_verify_access_from_code(uint32_t type_idx,
- AbstractMethod* referrer,
+mirror::Object* art_initialize_type_and_verify_access_from_code(uint32_t type_idx,
+ mirror::AbstractMethod* referrer,
Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Called when caller isn't guaranteed to have access to a type and the dex cache may be
@@ -326,14 +326,14 @@
return ResolveVerifyAndClinit(type_idx, referrer, thread, false, true);
}
-Object* art_resolve_string_from_code(AbstractMethod* referrer, uint32_t string_idx)
+mirror::Object* art_resolve_string_from_code(mirror::AbstractMethod* referrer, uint32_t string_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return ResolveStringFromCode(referrer, string_idx);
}
-int32_t art_set32_static_from_code(uint32_t field_idx, AbstractMethod* referrer, int32_t new_value)
+int32_t art_set32_static_from_code(uint32_t field_idx, mirror::AbstractMethod* referrer, int32_t new_value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(uint32_t));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(uint32_t));
if (LIKELY(field != NULL)) {
field->Set32(field->GetDeclaringClass(), new_value);
return 0;
@@ -347,9 +347,9 @@
return -1;
}
-int32_t art_set64_static_from_code(uint32_t field_idx, AbstractMethod* referrer, int64_t new_value)
+int32_t art_set64_static_from_code(uint32_t field_idx, mirror::AbstractMethod* referrer, int64_t new_value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(uint64_t));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(uint64_t));
if (LIKELY(field != NULL)) {
field->Set64(field->GetDeclaringClass(), new_value);
return 0;
@@ -363,15 +363,15 @@
return -1;
}
-int32_t art_set_obj_static_from_code(uint32_t field_idx, AbstractMethod* referrer, Object* new_value)
+int32_t art_set_obj_static_from_code(uint32_t field_idx, mirror::AbstractMethod* referrer, mirror::Object* new_value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, StaticObjectWrite, sizeof(Object*));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, StaticObjectWrite, sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
field->SetObj(field->GetDeclaringClass(), new_value);
return 0;
}
field = FindFieldFromCode(field_idx, referrer, Thread::Current(),
- StaticObjectWrite, sizeof(Object*));
+ StaticObjectWrite, sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
field->SetObj(field->GetDeclaringClass(), new_value);
return 0;
@@ -379,9 +379,9 @@
return -1;
}
-int32_t art_get32_static_from_code(uint32_t field_idx, AbstractMethod* referrer)
+int32_t art_get32_static_from_code(uint32_t field_idx, mirror::AbstractMethod* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(uint32_t));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(uint32_t));
if (LIKELY(field != NULL)) {
return field->Get32(field->GetDeclaringClass());
}
@@ -393,9 +393,9 @@
return 0;
}
-int64_t art_get64_static_from_code(uint32_t field_idx, AbstractMethod* referrer)
+int64_t art_get64_static_from_code(uint32_t field_idx, mirror::AbstractMethod* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(uint64_t));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(uint64_t));
if (LIKELY(field != NULL)) {
return field->Get64(field->GetDeclaringClass());
}
@@ -407,24 +407,24 @@
return 0;
}
-Object* art_get_obj_static_from_code(uint32_t field_idx, AbstractMethod* referrer)
+mirror::Object* art_get_obj_static_from_code(uint32_t field_idx, mirror::AbstractMethod* referrer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, StaticObjectRead, sizeof(Object*));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, StaticObjectRead, sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
return field->GetObj(field->GetDeclaringClass());
}
field = FindFieldFromCode(field_idx, referrer, Thread::Current(),
- StaticObjectRead, sizeof(Object*));
+ StaticObjectRead, sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
return field->GetObj(field->GetDeclaringClass());
}
return 0;
}
-int32_t art_set32_instance_from_code(uint32_t field_idx, AbstractMethod* referrer,
- Object* obj, uint32_t new_value)
+int32_t art_set32_instance_from_code(uint32_t field_idx, mirror::AbstractMethod* referrer,
+ mirror::Object* obj, uint32_t new_value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(uint32_t));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(uint32_t));
if (LIKELY(field != NULL)) {
field->Set32(obj, new_value);
return 0;
@@ -438,10 +438,10 @@
return -1;
}
-int32_t art_set64_instance_from_code(uint32_t field_idx, AbstractMethod* referrer,
- Object* obj, int64_t new_value)
+int32_t art_set64_instance_from_code(uint32_t field_idx, mirror::AbstractMethod* referrer,
+ mirror::Object* obj, int64_t new_value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(uint64_t));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(uint64_t));
if (LIKELY(field != NULL)) {
field->Set64(obj, new_value);
return 0;
@@ -455,16 +455,16 @@
return -1;
}
-int32_t art_set_obj_instance_from_code(uint32_t field_idx, AbstractMethod* referrer,
- Object* obj, Object* new_value)
+int32_t art_set_obj_instance_from_code(uint32_t field_idx, mirror::AbstractMethod* referrer,
+ mirror::Object* obj, mirror::Object* new_value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite, sizeof(Object*));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite, sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
field->SetObj(obj, new_value);
return 0;
}
field = FindFieldFromCode(field_idx, referrer, Thread::Current(),
- InstanceObjectWrite, sizeof(Object*));
+ InstanceObjectWrite, sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
field->SetObj(obj, new_value);
return 0;
@@ -472,9 +472,9 @@
return -1;
}
-int32_t art_get32_instance_from_code(uint32_t field_idx, AbstractMethod* referrer, Object* obj)
+int32_t art_get32_instance_from_code(uint32_t field_idx, mirror::AbstractMethod* referrer, mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(uint32_t));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(uint32_t));
if (LIKELY(field != NULL)) {
return field->Get32(obj);
}
@@ -486,9 +486,9 @@
return 0;
}
-int64_t art_get64_instance_from_code(uint32_t field_idx, AbstractMethod* referrer, Object* obj)
+int64_t art_get64_instance_from_code(uint32_t field_idx, mirror::AbstractMethod* referrer, mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(uint64_t));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(uint64_t));
if (LIKELY(field != NULL)) {
return field->Get64(obj);
}
@@ -500,22 +500,22 @@
return 0;
}
-Object* art_get_obj_instance_from_code(uint32_t field_idx, AbstractMethod* referrer, Object* obj)
+mirror::Object* art_get_obj_instance_from_code(uint32_t field_idx, mirror::AbstractMethod* referrer, mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, InstanceObjectRead, sizeof(Object*));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, InstanceObjectRead, sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
return field->GetObj(obj);
}
field = FindFieldFromCode(field_idx, referrer, Thread::Current(),
- InstanceObjectRead, sizeof(Object*));
+ InstanceObjectRead, sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
return field->GetObj(obj);
}
return 0;
}
-void art_fill_array_data_from_code(AbstractMethod* method, uint32_t dex_pc,
- Array* array, uint32_t payload_offset)
+void art_fill_array_data_from_code(mirror::AbstractMethod* method, uint32_t dex_pc,
+ mirror::Array* array, uint32_t payload_offset)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Test: Is array equal to null? (Guard NullPointerException)
if (UNLIKELY(array == NULL)) {
@@ -555,14 +555,14 @@
// Type checking, in the nature of casting
//----------------------------------------------------------------------------
-int32_t art_is_assignable_from_code(const Class* dest_type, const Class* src_type)
+int32_t art_is_assignable_from_code(const mirror::Class* dest_type, const mirror::Class* src_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(dest_type != NULL);
DCHECK(src_type != NULL);
return dest_type->IsAssignableFrom(src_type) ? 1 : 0;
}
-void art_check_cast_from_code(const Class* dest_type, const Class* src_type)
+void art_check_cast_from_code(const mirror::Class* dest_type, const mirror::Class* src_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(dest_type->IsClass()) << PrettyClass(dest_type);
DCHECK(src_type->IsClass()) << PrettyClass(src_type);
@@ -574,16 +574,16 @@
}
}
-void art_check_put_array_element_from_code(const Object* element, const Object* array)
+void art_check_put_array_element_from_code(const mirror::Object* element, const mirror::Object* array)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (element == NULL) {
return;
}
DCHECK(array != NULL);
- Class* array_class = array->GetClass();
+ mirror::Class* array_class = array->GetClass();
DCHECK(array_class != NULL);
- Class* component_type = array_class->GetComponentType();
- Class* element_class = element->GetClass();
+ mirror::Class* component_type = array_class->GetComponentType();
+ mirror::Class* element_class = element->GetClass();
if (UNLIKELY(!component_type->IsAssignableFrom(element_class))) {
Thread::Current()->ThrowNewExceptionF("Ljava/lang/ArrayStoreException;",
"%s cannot be stored in an array of type %s",
@@ -634,11 +634,11 @@
PopLocalReferences(saved_local_ref_cookie, self);
}
-Object* art_jni_method_end_with_reference(jobject result, uint32_t saved_local_ref_cookie,
+mirror::Object* art_jni_method_end_with_reference(jobject result, uint32_t saved_local_ref_cookie,
Thread* self)
SHARED_LOCK_FUNCTION(Locks::mutator_lock_) {
self->TransitionFromSuspendedToRunnable();
- Object* o = self->DecodeJObject(result); // Must decode before pop.
+ mirror::Object* o = self->DecodeJObject(result); // Must decode before pop.
PopLocalReferences(saved_local_ref_cookie, self);
// Process result.
if (UNLIKELY(self->GetJniEnv()->check_jni)) {
@@ -650,13 +650,13 @@
return o;
}
-Object* art_jni_method_end_with_reference_synchronized(jobject result,
+mirror::Object* art_jni_method_end_with_reference_synchronized(jobject result,
uint32_t saved_local_ref_cookie,
jobject locked, Thread* self)
SHARED_LOCK_FUNCTION(Locks::mutator_lock_) {
self->TransitionFromSuspendedToRunnable();
UnlockJniSynchronizedMethod(locked, self); // Must decode before pop.
- Object* o = self->DecodeJObject(result);
+ mirror::Object* o = self->DecodeJObject(result);
PopLocalReferences(saved_local_ref_cookie, self);
// Process result.
if (UNLIKELY(self->GetJniEnv()->check_jni)) {
@@ -711,12 +711,12 @@
// Handler for invocation on proxy methods. Create a boxed argument array and invoke the invocation
// handler which is a field within the proxy object receiver. The var args encode the arguments
// with the last argument being a pointer to a JValue to store the result in.
-void art_proxy_invoke_handler_from_code(AbstractMethod* proxy_method, ...)
+void art_proxy_invoke_handler_from_code(mirror::AbstractMethod* proxy_method, ...)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
va_list ap;
va_start(ap, proxy_method);
- Object* receiver = va_arg(ap, Object*);
+ mirror::Object* receiver = va_arg(ap, mirror::Object*);
Thread* self = va_arg(ap, Thread*);
MethodHelper proxy_mh(proxy_method);
@@ -734,19 +734,19 @@
jobject rcvr_jobj = soa.AddLocalReference<jobject>(receiver);
// Convert proxy method into expected interface method.
- AbstractMethod* interface_method = proxy_method->FindOverriddenMethod();
+ mirror::AbstractMethod* interface_method = proxy_method->FindOverriddenMethod();
DCHECK(interface_method != NULL);
DCHECK(!interface_method->IsProxyMethod()) << PrettyMethod(interface_method);
jobject interface_method_jobj = soa.AddLocalReference<jobject>(interface_method);
- // Record arguments and turn Object* arguments into jobject to survive GC.
+ // Record arguments and turn mirror::Object* arguments into jobject to survive GC.
std::vector<jvalue> args;
const size_t num_params = proxy_mh.NumArgs();
for (size_t i = 1; i < num_params; ++i) {
jvalue val;
switch (proxy_mh.GetParamPrimitiveType(i)) {
case Primitive::kPrimNot:
- val.l = soa.AddLocalReference<jobject>(va_arg(ap, Object*));
+ val.l = soa.AddLocalReference<jobject>(va_arg(ap, mirror::Object*));
break;
case Primitive::kPrimBoolean: // Fall-through.
case Primitive::kPrimByte: // Fall-through.
diff --git a/src/compiler_llvm/runtime_support_llvm.h b/src/compiler_llvm/runtime_support_llvm.h
index 6c133c9..6a0b339 100644
--- a/src/compiler_llvm/runtime_support_llvm.h
+++ b/src/compiler_llvm/runtime_support_llvm.h
@@ -17,7 +17,7 @@
#ifndef ART_SRC_COMPILER_LLVM_RUNTIME_SUPPORT_LLVM_H_
#define ART_SRC_COMPILER_LLVM_RUNTIME_SUPPORT_LLVM_H_
-#include "object.h"
+#include "mirror/object.h"
namespace art {
diff --git a/src/compiler_llvm/stub_compiler.cc b/src/compiler_llvm/stub_compiler.cc
index d03400f..3a28b87 100644
--- a/src/compiler_llvm/stub_compiler.cc
+++ b/src/compiler_llvm/stub_compiler.cc
@@ -22,7 +22,7 @@
#include "compiler.h"
#include "compiler_llvm.h"
#include "ir_builder.h"
-#include "object.h"
+#include "mirror/object.h"
#include "runtime_support_func.h"
#include "utils_llvm.h"
diff --git a/src/compiler_test.cc b/src/compiler_test.cc
index f513511..bd25eb3 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -22,10 +22,13 @@
#include "UniquePtr.h"
#include "class_linker.h"
#include "common_test.h"
-#include "dex_cache.h"
#include "dex_file.h"
#include "heap.h"
-#include "object.h"
+#include "mirror/class.h"
+#include "mirror/class-inl.h"
+#include "mirror/dex_cache.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object_array-inl.h"
namespace art {
@@ -69,7 +72,7 @@
const DexFile::ClassDef& class_def = dex_file.GetClassDef(i);
const char* descriptor = dex_file.GetClassDescriptor(class_def);
ScopedObjectAccess soa(Thread::Current());
- Class* c = class_linker->FindClass(descriptor, soa.Decode<ClassLoader*>(class_loader));
+ mirror::Class* c = class_linker->FindClass(descriptor, soa.Decode<mirror::ClassLoader*>(class_loader));
CHECK(c != NULL);
for (size_t i = 0; i < c->NumDirectMethods(); i++) {
MakeExecutable(c->GetDirectMethod(i));
@@ -92,21 +95,21 @@
// All libcore references should resolve
ScopedObjectAccess soa(Thread::Current());
const DexFile* dex = java_lang_dex_file_;
- DexCache* dex_cache = class_linker_->FindDexCache(*dex);
+ mirror::DexCache* dex_cache = class_linker_->FindDexCache(*dex);
EXPECT_EQ(dex->NumStringIds(), dex_cache->NumStrings());
for (size_t i = 0; i < dex_cache->NumStrings(); i++) {
- const String* string = dex_cache->GetResolvedString(i);
+ const mirror::String* string = dex_cache->GetResolvedString(i);
EXPECT_TRUE(string != NULL) << "string_idx=" << i;
}
EXPECT_EQ(dex->NumTypeIds(), dex_cache->NumResolvedTypes());
for (size_t i = 0; i < dex_cache->NumResolvedTypes(); i++) {
- Class* type = dex_cache->GetResolvedType(i);
+ mirror::Class* type = dex_cache->GetResolvedType(i);
EXPECT_TRUE(type != NULL) << "type_idx=" << i
<< " " << dex->GetTypeDescriptor(dex->GetTypeId(i));
}
EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumResolvedMethods());
for (size_t i = 0; i < dex_cache->NumResolvedMethods(); i++) {
- AbstractMethod* method = dex_cache->GetResolvedMethod(i);
+ mirror::AbstractMethod* method = dex_cache->GetResolvedMethod(i);
EXPECT_TRUE(method != NULL) << "method_idx=" << i
<< " " << dex->GetMethodDeclaringClassDescriptor(dex->GetMethodId(i))
<< " " << dex->GetMethodName(dex->GetMethodId(i));
@@ -117,7 +120,7 @@
}
EXPECT_EQ(dex->NumFieldIds(), dex_cache->NumResolvedFields());
for (size_t i = 0; i < dex_cache->NumResolvedFields(); i++) {
- Field* field = dex_cache->GetResolvedField(i);
+ mirror::Field* field = dex_cache->GetResolvedField(i);
EXPECT_TRUE(field != NULL) << "field_idx=" << i
<< " " << dex->GetFieldDeclaringClassDescriptor(dex->GetFieldId(i))
<< " " << dex->GetFieldName(dex->GetFieldId(i));
diff --git a/src/debugger.cc b/src/debugger.cc
index 3e93511..3121725 100644
--- a/src/debugger.cc
+++ b/src/debugger.cc
@@ -21,10 +21,19 @@
#include <set>
#include "class_linker.h"
-#include "class_loader.h"
+#include "class_linker-inl.h"
#include "dex_instruction.h"
+#include "gc/card_table-inl.h"
#include "gc/large_object_space.h"
#include "gc/space.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/class.h"
+#include "mirror/class-inl.h"
+#include "mirror/class_loader.h"
+#include "mirror/field-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
+#include "mirror/throwable.h"
#include "oat/runtime/context.h"
#include "object_utils.h"
#include "safe_map.h"
@@ -34,6 +43,7 @@
#include "sirt_ref.h"
#include "stack_indirect_reference_table.h"
#include "thread_list.h"
+#include "utf.h"
#include "well_known_classes.h"
namespace art {
@@ -42,14 +52,14 @@
static const size_t kNumAllocRecords = 512; // Must be power of 2.
static const uintptr_t kInvalidId = 1;
-static const Object* kInvalidObject = reinterpret_cast<Object*>(kInvalidId);
+static const mirror::Object* kInvalidObject = reinterpret_cast<mirror::Object*>(kInvalidId);
class ObjectRegistry {
public:
ObjectRegistry() : lock_("ObjectRegistry lock") {
}
- JDWP::ObjectId Add(Object* o) {
+ JDWP::ObjectId Add(mirror::Object* o) {
if (o == NULL) {
return 0;
}
@@ -76,14 +86,14 @@
}
MutexLock mu(Thread::Current(), lock_);
- typedef SafeMap<JDWP::ObjectId, Object*>::iterator It; // C++0x auto
+ typedef SafeMap<JDWP::ObjectId, mirror::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) {
+ void VisitRoots(RootVisitor* visitor, void* arg) {
MutexLock mu(Thread::Current(), lock_);
- typedef SafeMap<JDWP::ObjectId, Object*>::iterator It; // C++0x auto
+ typedef SafeMap<JDWP::ObjectId, mirror::Object*>::iterator It; // C++0x auto
for (It it = map_.begin(); it != map_.end(); ++it) {
visitor(it->second, arg);
}
@@ -91,11 +101,11 @@
private:
Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
- SafeMap<JDWP::ObjectId, Object*> map_;
+ SafeMap<JDWP::ObjectId, mirror::Object*> map_;
};
struct AllocRecordStackTraceElement {
- AbstractMethod* method;
+ mirror::AbstractMethod* method;
uint32_t dex_pc;
int32_t LineNumber() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -104,7 +114,7 @@
};
struct AllocRecord {
- Class* type;
+ mirror::Class* type;
size_t byte_count;
uint16_t thin_lock_id;
AllocRecordStackTraceElement stack[kMaxAllocRecordStackDepth]; // Unused entries have NULL method.
@@ -119,9 +129,9 @@
};
struct Breakpoint {
- AbstractMethod* method;
+ mirror::AbstractMethod* method;
uint32_t dex_pc;
- Breakpoint(AbstractMethod* method, uint32_t dex_pc) : method(method), dex_pc(dex_pc) {}
+ Breakpoint(mirror::AbstractMethod* method, uint32_t dex_pc) : method(method), dex_pc(dex_pc) {}
};
static std::ostream& operator<<(std::ostream& os, const Breakpoint& rhs)
@@ -138,7 +148,7 @@
JDWP::JdwpStepSize step_size;
JDWP::JdwpStepDepth step_depth;
- const AbstractMethod* method;
+ const mirror::AbstractMethod* method;
int32_t line_number; // Or -1 for native methods.
std::set<uint32_t> dex_pcs;
int stack_depth;
@@ -180,7 +190,7 @@
static std::vector<Breakpoint> gBreakpoints GUARDED_BY(Locks::breakpoint_lock_);
static SingleStepControl gSingleStepControl GUARDED_BY(Locks::breakpoint_lock_);
-static bool IsBreakpoint(AbstractMethod* m, uint32_t dex_pc)
+static bool IsBreakpoint(mirror::AbstractMethod* m, uint32_t dex_pc)
LOCKS_EXCLUDED(Locks::breakpoint_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
MutexLock mu(Thread::Current(), *Locks::breakpoint_lock_);
@@ -200,9 +210,9 @@
return thread->IsSuspended() && thread->GetDebugSuspendCount() > 0;
}
-static Array* DecodeArray(JDWP::RefTypeId id, JDWP::JdwpError& status)
+static mirror::Array* DecodeArray(JDWP::RefTypeId id, JDWP::JdwpError& status)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Object* o = gRegistry->Get<Object*>(id);
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(id);
if (o == NULL || o == kInvalidObject) {
status = JDWP::ERR_INVALID_OBJECT;
return NULL;
@@ -215,9 +225,9 @@
return o->AsArray();
}
-static Class* DecodeClass(JDWP::RefTypeId id, JDWP::JdwpError& status)
+static mirror::Class* DecodeClass(JDWP::RefTypeId id, JDWP::JdwpError& status)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Object* o = gRegistry->Get<Object*>(id);
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(id);
if (o == NULL || o == kInvalidObject) {
status = JDWP::ERR_INVALID_OBJECT;
return NULL;
@@ -234,13 +244,13 @@
EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_)
LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Object* thread_peer = gRegistry->Get<Object*>(thread_id);
+ mirror::Object* thread_peer = gRegistry->Get<mirror::Object*>(thread_id);
if (thread_peer == NULL || thread_peer == kInvalidObject) {
// This isn't even an object.
return JDWP::ERR_INVALID_OBJECT;
}
- Class* java_lang_Thread = soa.Decode<Class*>(WellKnownClasses::java_lang_Thread);
+ mirror::Class* java_lang_Thread = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_Thread);
if (!java_lang_Thread->IsAssignableFrom(thread_peer->GetClass())) {
// This isn't a thread.
return JDWP::ERR_INVALID_THREAD;
@@ -260,7 +270,7 @@
return static_cast<JDWP::JdwpTag>(descriptor[0]);
}
-static JDWP::JdwpTag TagFromClass(Class* c)
+static JDWP::JdwpTag TagFromClass(mirror::Class* c)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK(c != NULL);
if (c->IsArrayClass()) {
@@ -291,7 +301,7 @@
*
* Null objects are tagged JT_OBJECT.
*/
-static JDWP::JdwpTag TagFromObject(const Object* o)
+static JDWP::JdwpTag TagFromObject(const mirror::Object* o)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return (o == NULL) ? JDWP::JT_OBJECT : TagFromClass(o->GetClass());
}
@@ -567,14 +577,14 @@
exit(status); // This is all dalvik did.
}
-void Dbg::VisitRoots(Heap::RootVisitor* visitor, void* arg) {
+void Dbg::VisitRoots(RootVisitor* visitor, void* arg) {
if (gRegistry != NULL) {
gRegistry->VisitRoots(visitor, arg);
}
}
std::string Dbg::GetClassName(JDWP::RefTypeId class_id) {
- Object* o = gRegistry->Get<Object*>(class_id);
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(class_id);
if (o == NULL) {
return "NULL";
}
@@ -589,7 +599,7 @@
JDWP::JdwpError Dbg::GetClassObject(JDWP::RefTypeId id, JDWP::ObjectId& class_object_id) {
JDWP::JdwpError status;
- Class* c = DecodeClass(id, status);
+ mirror::Class* c = DecodeClass(id, status);
if (c == NULL) {
return status;
}
@@ -599,7 +609,7 @@
JDWP::JdwpError Dbg::GetSuperclass(JDWP::RefTypeId id, JDWP::RefTypeId& superclass_id) {
JDWP::JdwpError status;
- Class* c = DecodeClass(id, status);
+ mirror::Class* c = DecodeClass(id, status);
if (c == NULL) {
return status;
}
@@ -613,7 +623,7 @@
}
JDWP::JdwpError Dbg::GetClassLoader(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply) {
- Object* o = gRegistry->Get<Object*>(id);
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(id);
if (o == NULL || o == kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
@@ -623,7 +633,7 @@
JDWP::JdwpError Dbg::GetModifiers(JDWP::RefTypeId id, JDWP::ExpandBuf* pReply) {
JDWP::JdwpError status;
- Class* c = DecodeClass(id, status);
+ mirror::Class* c = DecodeClass(id, status);
if (c == NULL) {
return status;
}
@@ -641,7 +651,7 @@
JDWP::JdwpError Dbg::GetMonitorInfo(JDWP::ObjectId object_id, JDWP::ExpandBuf* reply)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Object* o = gRegistry->Get<Object*>(object_id);
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
if (o == NULL || o == kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
@@ -699,14 +709,14 @@
return true;
}
- static void AppendOwnedMonitors(Object* owned_monitor, void* arg) {
+ static void AppendOwnedMonitors(mirror::Object* owned_monitor, void* arg) {
OwnedMonitorVisitor* visitor = reinterpret_cast<OwnedMonitorVisitor*>(arg);
visitor->monitors.push_back(owned_monitor);
visitor->stack_depths.push_back(visitor->current_stack_depth);
}
size_t current_stack_depth;
- std::vector<Object*> monitors;
+ std::vector<mirror::Object*> monitors;
std::vector<uint32_t> stack_depths;
};
UniquePtr<Context> context(Context::Create());
@@ -743,11 +753,11 @@
std::vector<uint64_t>& counts)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- std::vector<Class*> classes;
+ std::vector<mirror::Class*> classes;
counts.clear();
for (size_t i = 0; i < class_ids.size(); ++i) {
JDWP::JdwpError status;
- Class* c = DecodeClass(class_ids[i], status);
+ mirror::Class* c = DecodeClass(class_ids[i], status);
if (c == NULL) {
return status;
}
@@ -762,12 +772,12 @@
JDWP::JdwpError Dbg::GetInstances(JDWP::RefTypeId class_id, int32_t max_count, std::vector<JDWP::ObjectId>& instances)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
JDWP::JdwpError status;
- Class* c = DecodeClass(class_id, status);
+ mirror::Class* c = DecodeClass(class_id, status);
if (c == NULL) {
return status;
}
- std::vector<Object*> raw_instances;
+ std::vector<mirror::Object*> raw_instances;
Runtime::Current()->GetHeap()->GetInstances(c, max_count, raw_instances);
for (size_t i = 0; i < raw_instances.size(); ++i) {
instances.push_back(gRegistry->Add(raw_instances[i]));
@@ -778,12 +788,12 @@
JDWP::JdwpError Dbg::GetReferringObjects(JDWP::ObjectId object_id, int32_t max_count,
std::vector<JDWP::ObjectId>& referring_objects)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Object* o = gRegistry->Get<Object*>(object_id);
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
if (o == NULL || o == kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
- std::vector<Object*> raw_instances;
+ std::vector<mirror::Object*> raw_instances;
Runtime::Current()->GetHeap()->GetReferringObjects(o, max_count, raw_instances);
for (size_t i = 0; i < raw_instances.size(); ++i) {
referring_objects.push_back(gRegistry->Add(raw_instances[i]));
@@ -793,7 +803,7 @@
JDWP::JdwpError Dbg::GetReflectedType(JDWP::RefTypeId class_id, JDWP::ExpandBuf* pReply) {
JDWP::JdwpError status;
- Class* c = DecodeClass(class_id, status);
+ mirror::Class* c = DecodeClass(class_id, status);
if (c == NULL) {
return status;
}
@@ -811,11 +821,11 @@
explicit ClassListCreator(std::vector<JDWP::RefTypeId>& classes) : classes(classes) {
}
- static bool Visit(Class* c, void* arg) {
+ static bool Visit(mirror::Class* c, void* arg) {
return reinterpret_cast<ClassListCreator*>(arg)->Visit(c);
}
- bool Visit(Class* c) {
+ bool Visit(mirror::Class* c) {
if (!c->IsPrimitive()) {
classes.push_back(static_cast<JDWP::RefTypeId>(gRegistry->Add(c)));
}
@@ -831,7 +841,7 @@
JDWP::JdwpError Dbg::GetClassInfo(JDWP::RefTypeId class_id, JDWP::JdwpTypeTag* pTypeTag, uint32_t* pStatus, std::string* pDescriptor) {
JDWP::JdwpError status;
- Class* c = DecodeClass(class_id, status);
+ mirror::Class* c = DecodeClass(class_id, status);
if (c == NULL) {
return status;
}
@@ -855,7 +865,7 @@
}
void Dbg::FindLoadedClassBySignature(const char* descriptor, std::vector<JDWP::RefTypeId>& ids) {
- std::vector<Class*> classes;
+ std::vector<mirror::Class*> classes;
Runtime::Current()->GetClassLinker()->LookupClasses(descriptor, classes);
ids.clear();
for (size_t i = 0; i < classes.size(); ++i) {
@@ -864,7 +874,7 @@
}
JDWP::JdwpError Dbg::GetReferenceType(JDWP::ObjectId object_id, JDWP::ExpandBuf* pReply) {
- Object* o = gRegistry->Get<Object*>(object_id);
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
if (o == NULL || o == kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
@@ -887,7 +897,7 @@
JDWP::JdwpError Dbg::GetSignature(JDWP::RefTypeId class_id, std::string& signature) {
JDWP::JdwpError status;
- Class* c = DecodeClass(class_id, status);
+ mirror::Class* c = DecodeClass(class_id, status);
if (c == NULL) {
return status;
}
@@ -897,7 +907,7 @@
JDWP::JdwpError Dbg::GetSourceFile(JDWP::RefTypeId class_id, std::string& result) {
JDWP::JdwpError status;
- Class* c = DecodeClass(class_id, status);
+ mirror::Class* c = DecodeClass(class_id, status);
if (c == NULL) {
return status;
}
@@ -906,7 +916,7 @@
}
JDWP::JdwpError Dbg::GetObjectTag(JDWP::ObjectId object_id, uint8_t& tag) {
- Object* o = gRegistry->Get<Object*>(object_id);
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
if (o == kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
@@ -946,7 +956,7 @@
JDWP::JdwpError Dbg::GetArrayLength(JDWP::ObjectId array_id, int& length) {
JDWP::JdwpError status;
- Array* a = DecodeArray(array_id, status);
+ mirror::Array* a = DecodeArray(array_id, status);
if (a == NULL) {
return status;
}
@@ -956,7 +966,7 @@
JDWP::JdwpError Dbg::OutputArray(JDWP::ObjectId array_id, int offset, int count, JDWP::ExpandBuf* pReply) {
JDWP::JdwpError status;
- Array* a = DecodeArray(array_id, status);
+ mirror::Array* a = DecodeArray(array_id, status);
if (a == NULL) {
return status;
}
@@ -988,9 +998,9 @@
memcpy(dst, &src[offset * width], count * width);
}
} else {
- ObjectArray<Object>* oa = a->AsObjectArray<Object>();
+ mirror::ObjectArray<mirror::Object>* oa = a->AsObjectArray<mirror::Object>();
for (int i = 0; i < count; ++i) {
- Object* element = oa->Get(offset + i);
+ mirror::Object* element = oa->Get(offset + i);
JDWP::JdwpTag specific_tag = (element != NULL) ? TagFromObject(element) : tag;
expandBufAdd1(pReply, specific_tag);
expandBufAddObjectId(pReply, gRegistry->Add(element));
@@ -1004,7 +1014,7 @@
const uint8_t* src)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
JDWP::JdwpError status;
- Array* a = DecodeArray(array_id, status);
+ mirror::Array* a = DecodeArray(array_id, status);
if (a == NULL) {
return status;
}
@@ -1040,10 +1050,10 @@
memcpy(&dst[offset * width], src, count * width);
}
} else {
- ObjectArray<Object>* oa = a->AsObjectArray<Object>();
+ mirror::ObjectArray<mirror::Object>* oa = a->AsObjectArray<mirror::Object>();
for (int i = 0; i < count; ++i) {
JDWP::ObjectId id = JDWP::ReadObjectId(&src);
- Object* o = gRegistry->Get<Object*>(id);
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(id);
if (o == kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
@@ -1055,12 +1065,12 @@
}
JDWP::ObjectId Dbg::CreateString(const std::string& str) {
- return gRegistry->Add(String::AllocFromModifiedUtf8(Thread::Current(), str.c_str()));
+ return gRegistry->Add(mirror::String::AllocFromModifiedUtf8(Thread::Current(), str.c_str()));
}
JDWP::JdwpError Dbg::CreateObject(JDWP::RefTypeId class_id, JDWP::ObjectId& new_object) {
JDWP::JdwpError status;
- Class* c = DecodeClass(class_id, status);
+ mirror::Class* c = DecodeClass(class_id, status);
if (c == NULL) {
return status;
}
@@ -1074,24 +1084,24 @@
JDWP::JdwpError Dbg::CreateArrayObject(JDWP::RefTypeId array_class_id, uint32_t length,
JDWP::ObjectId& new_array) {
JDWP::JdwpError status;
- Class* c = DecodeClass(array_class_id, status);
+ mirror::Class* c = DecodeClass(array_class_id, status);
if (c == NULL) {
return status;
}
- new_array = gRegistry->Add(Array::Alloc(Thread::Current(), c, length));
+ new_array = gRegistry->Add(mirror::Array::Alloc(Thread::Current(), c, length));
return JDWP::ERR_NONE;
}
bool Dbg::MatchType(JDWP::RefTypeId instance_class_id, JDWP::RefTypeId class_id) {
JDWP::JdwpError status;
- Class* c1 = DecodeClass(instance_class_id, status);
+ mirror::Class* c1 = DecodeClass(instance_class_id, status);
CHECK(c1 != NULL);
- Class* c2 = DecodeClass(class_id, status);
+ mirror::Class* c2 = DecodeClass(class_id, status);
CHECK(c2 != NULL);
return c1->IsAssignableFrom(c2);
}
-static JDWP::FieldId ToFieldId(const Field* f)
+static JDWP::FieldId ToFieldId(const mirror::Field* f)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#ifdef MOVING_GARBAGE_COLLECTOR
UNIMPLEMENTED(FATAL);
@@ -1100,7 +1110,7 @@
#endif
}
-static JDWP::MethodId ToMethodId(const AbstractMethod* m)
+static JDWP::MethodId ToMethodId(const mirror::AbstractMethod* m)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#ifdef MOVING_GARBAGE_COLLECTOR
UNIMPLEMENTED(FATAL);
@@ -1109,30 +1119,30 @@
#endif
}
-static Field* FromFieldId(JDWP::FieldId fid)
+static mirror::Field* FromFieldId(JDWP::FieldId fid)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#ifdef MOVING_GARBAGE_COLLECTOR
UNIMPLEMENTED(FATAL);
#else
- return reinterpret_cast<Field*>(static_cast<uintptr_t>(fid));
+ return reinterpret_cast<mirror::Field*>(static_cast<uintptr_t>(fid));
#endif
}
-static AbstractMethod* FromMethodId(JDWP::MethodId mid)
+static mirror::AbstractMethod* FromMethodId(JDWP::MethodId mid)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#ifdef MOVING_GARBAGE_COLLECTOR
UNIMPLEMENTED(FATAL);
#else
- return reinterpret_cast<AbstractMethod*>(static_cast<uintptr_t>(mid));
+ return reinterpret_cast<mirror::AbstractMethod*>(static_cast<uintptr_t>(mid));
#endif
}
-static void SetLocation(JDWP::JdwpLocation& location, AbstractMethod* m, uint32_t dex_pc)
+static void SetLocation(JDWP::JdwpLocation& location, mirror::AbstractMethod* m, uint32_t dex_pc)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (m == NULL) {
memset(&location, 0, sizeof(location));
} else {
- Class* c = m->GetDeclaringClass();
+ mirror::Class* c = m->GetDeclaringClass();
location.type_tag = c->IsInterface() ? JDWP::TT_INTERFACE : JDWP::TT_CLASS;
location.class_id = gRegistry->Add(c);
location.method_id = ToMethodId(m);
@@ -1142,13 +1152,13 @@
std::string Dbg::GetMethodName(JDWP::MethodId method_id)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* m = FromMethodId(method_id);
+ mirror::AbstractMethod* m = FromMethodId(method_id);
return MethodHelper(m).GetName();
}
std::string Dbg::GetFieldName(JDWP::FieldId field_id)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* f = FromFieldId(field_id);
+ mirror::Field* f = FromFieldId(field_id);
return FieldHelper(f).GetName();
}
@@ -1190,7 +1200,7 @@
return newSlot;
}
-static uint16_t DemangleSlot(uint16_t slot, AbstractMethod* m)
+static uint16_t DemangleSlot(uint16_t slot, mirror::AbstractMethod* m)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (slot == kEclipseWorkaroundSlot) {
return 0;
@@ -1204,7 +1214,7 @@
JDWP::JdwpError Dbg::OutputDeclaredFields(JDWP::RefTypeId class_id, bool with_generic, JDWP::ExpandBuf* pReply) {
JDWP::JdwpError status;
- Class* c = DecodeClass(class_id, status);
+ mirror::Class* c = DecodeClass(class_id, status);
if (c == NULL) {
return status;
}
@@ -1215,7 +1225,7 @@
expandBufAdd4BE(pReply, instance_field_count + static_field_count);
for (size_t i = 0; i < instance_field_count + static_field_count; ++i) {
- Field* f = (i < instance_field_count) ? c->GetInstanceField(i) : c->GetStaticField(i - instance_field_count);
+ mirror::Field* f = (i < instance_field_count) ? c->GetInstanceField(i) : c->GetStaticField(i - instance_field_count);
FieldHelper fh(f);
expandBufAddFieldId(pReply, ToFieldId(f));
expandBufAddUtf8String(pReply, fh.GetName());
@@ -1232,7 +1242,7 @@
JDWP::JdwpError Dbg::OutputDeclaredMethods(JDWP::RefTypeId class_id, bool with_generic,
JDWP::ExpandBuf* pReply) {
JDWP::JdwpError status;
- Class* c = DecodeClass(class_id, status);
+ mirror::Class* c = DecodeClass(class_id, status);
if (c == NULL) {
return status;
}
@@ -1243,7 +1253,7 @@
expandBufAdd4BE(pReply, direct_method_count + virtual_method_count);
for (size_t i = 0; i < direct_method_count + virtual_method_count; ++i) {
- AbstractMethod* m = (i < direct_method_count) ? c->GetDirectMethod(i) : c->GetVirtualMethod(i - direct_method_count);
+ mirror::AbstractMethod* m = (i < direct_method_count) ? c->GetDirectMethod(i) : c->GetVirtualMethod(i - direct_method_count);
MethodHelper mh(m);
expandBufAddMethodId(pReply, ToMethodId(m));
expandBufAddUtf8String(pReply, mh.GetName());
@@ -1259,7 +1269,7 @@
JDWP::JdwpError Dbg::OutputDeclaredInterfaces(JDWP::RefTypeId class_id, JDWP::ExpandBuf* pReply) {
JDWP::JdwpError status;
- Class* c = DecodeClass(class_id, status);
+ mirror::Class* c = DecodeClass(class_id, status);
if (c == NULL) {
return status;
}
@@ -1287,7 +1297,7 @@
return true;
}
};
- AbstractMethod* m = FromMethodId(method_id);
+ mirror::AbstractMethod* m = FromMethodId(method_id);
MethodHelper mh(m);
uint64_t start, end;
if (m->IsNative()) {
@@ -1341,14 +1351,14 @@
++pContext->variable_count;
}
};
- AbstractMethod* m = FromMethodId(method_id);
+ mirror::AbstractMethod* m = FromMethodId(method_id);
MethodHelper mh(m);
const DexFile::CodeItem* code_item = mh.GetCodeItem();
// arg_count considers doubles and longs to take 2 units.
// variable_count considers everything to take 1 unit.
std::string shorty(mh.GetShorty());
- expandBufAdd4BE(pReply, AbstractMethod::NumArgRegisters(shorty));
+ expandBufAdd4BE(pReply, mirror::AbstractMethod::NumArgRegisters(shorty));
// We don't know the total number of variables yet, so leave a blank and update it later.
size_t variable_count_offset = expandBufGetLength(pReply);
@@ -1368,7 +1378,7 @@
JDWP::JdwpError Dbg::GetBytecodes(JDWP::RefTypeId, JDWP::MethodId method_id,
std::vector<uint8_t>& bytecodes)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* m = FromMethodId(method_id);
+ mirror::AbstractMethod* m = FromMethodId(method_id);
if (m == NULL) {
return JDWP::ERR_INVALID_METHODID;
}
@@ -1396,18 +1406,18 @@
bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
JDWP::JdwpError status;
- Class* c = DecodeClass(ref_type_id, status);
+ mirror::Class* c = DecodeClass(ref_type_id, status);
if (ref_type_id != 0 && c == NULL) {
return status;
}
- Object* o = gRegistry->Get<Object*>(object_id);
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
if ((!is_static && o == NULL) || o == kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
- Field* f = FromFieldId(field_id);
+ mirror::Field* f = FromFieldId(field_id);
- Class* receiver_class = c;
+ mirror::Class* receiver_class = c;
if (receiver_class == NULL && o != NULL) {
receiver_class = o->GetClass();
}
@@ -1448,7 +1458,7 @@
LOG(FATAL) << "Unknown tag: " << tag;
}
} else {
- Object* value = f->GetObject(o);
+ mirror::Object* value = f->GetObject(o);
expandBufAdd1(pReply, TagFromObject(value));
expandBufAddObjectId(pReply, gRegistry->Add(value));
}
@@ -1467,11 +1477,11 @@
static JDWP::JdwpError SetFieldValueImpl(JDWP::ObjectId object_id, JDWP::FieldId field_id,
uint64_t value, int width, bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Object* o = gRegistry->Get<Object*>(object_id);
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(object_id);
if ((!is_static && o == NULL) || o == kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
- Field* f = FromFieldId(field_id);
+ mirror::Field* f = FromFieldId(field_id);
// The RI only enforces the static/non-static mismatch in one direction.
// TODO: should we change the tests and check both?
@@ -1499,12 +1509,12 @@
f->Set32(o, value);
}
} else {
- Object* v = gRegistry->Get<Object*>(value);
+ mirror::Object* v = gRegistry->Get<mirror::Object*>(value);
if (v == kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
if (v != NULL) {
- Class* field_type = FieldHelper(f).GetType();
+ mirror::Class* field_type = FieldHelper(f).GetType();
if (!field_type->IsAssignableFrom(v->GetClass())) {
return JDWP::ERR_INVALID_OBJECT;
}
@@ -1525,7 +1535,7 @@
}
std::string Dbg::StringToUtf8(JDWP::ObjectId string_id) {
- String* s = gRegistry->Get<String*>(string_id);
+ mirror::String* s = gRegistry->Get<mirror::String*>(string_id);
return s->ToModifiedUtf8();
}
@@ -1539,9 +1549,11 @@
}
// We still need to report the zombie threads' names, so we can't just call Thread::GetThreadName.
- Object* thread_object = gRegistry->Get<Object*>(thread_id);
- Field* java_lang_Thread_name_field = soa.DecodeField(WellKnownClasses::java_lang_Thread_name);
- String* s = reinterpret_cast<String*>(java_lang_Thread_name_field->GetObject(thread_object));
+ mirror::Object* thread_object = gRegistry->Get<mirror::Object*>(thread_id);
+ mirror::Field* java_lang_Thread_name_field =
+ soa.DecodeField(WellKnownClasses::java_lang_Thread_name);
+ mirror::String* s =
+ reinterpret_cast<mirror::String*>(java_lang_Thread_name_field->GetObject(thread_object));
if (s != NULL) {
name = s->ToModifiedUtf8();
}
@@ -1550,7 +1562,7 @@
JDWP::JdwpError Dbg::GetThreadGroup(JDWP::ObjectId thread_id, JDWP::ExpandBuf* pReply) {
ScopedObjectAccess soa(Thread::Current());
- Object* thread_object = gRegistry->Get<Object*>(thread_id);
+ mirror::Object* thread_object = gRegistry->Get<mirror::Object*>(thread_id);
if (thread_object == kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
@@ -1568,11 +1580,11 @@
return error;
}
- Class* c = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/Thread;");
+ mirror::Class* c = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/Thread;");
CHECK(c != NULL);
- Field* f = c->FindInstanceField("group", "Ljava/lang/ThreadGroup;");
+ mirror::Field* f = c->FindInstanceField("group", "Ljava/lang/ThreadGroup;");
CHECK(f != NULL);
- Object* group = f->GetObject(thread_object);
+ mirror::Object* group = f->GetObject(thread_object);
CHECK(group != NULL);
JDWP::ObjectId thread_group_id = gRegistry->Add(group);
@@ -1582,40 +1594,40 @@
std::string Dbg::GetThreadGroupName(JDWP::ObjectId thread_group_id) {
ScopedObjectAccess soa(Thread::Current());
- Object* thread_group = gRegistry->Get<Object*>(thread_group_id);
+ mirror::Object* thread_group = gRegistry->Get<mirror::Object*>(thread_group_id);
CHECK(thread_group != NULL);
- Class* c = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/ThreadGroup;");
+ mirror::Class* c = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/ThreadGroup;");
CHECK(c != NULL);
- Field* f = c->FindInstanceField("name", "Ljava/lang/String;");
+ mirror::Field* f = c->FindInstanceField("name", "Ljava/lang/String;");
CHECK(f != NULL);
- String* s = reinterpret_cast<String*>(f->GetObject(thread_group));
+ mirror::String* s = reinterpret_cast<mirror::String*>(f->GetObject(thread_group));
return s->ToModifiedUtf8();
}
JDWP::ObjectId Dbg::GetThreadGroupParent(JDWP::ObjectId thread_group_id) {
- Object* thread_group = gRegistry->Get<Object*>(thread_group_id);
+ mirror::Object* thread_group = gRegistry->Get<mirror::Object*>(thread_group_id);
CHECK(thread_group != NULL);
- Class* c = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/ThreadGroup;");
+ mirror::Class* c = Runtime::Current()->GetClassLinker()->FindSystemClass("Ljava/lang/ThreadGroup;");
CHECK(c != NULL);
- Field* f = c->FindInstanceField("parent", "Ljava/lang/ThreadGroup;");
+ mirror::Field* f = c->FindInstanceField("parent", "Ljava/lang/ThreadGroup;");
CHECK(f != NULL);
- Object* parent = f->GetObject(thread_group);
+ mirror::Object* parent = f->GetObject(thread_group);
return gRegistry->Add(parent);
}
JDWP::ObjectId Dbg::GetSystemThreadGroupId() {
ScopedObjectAccessUnchecked soa(Thread::Current());
- Field* f = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup);
- Object* group = f->GetObject(f->GetDeclaringClass());
+ mirror::Field* f = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_systemThreadGroup);
+ mirror::Object* group = f->GetObject(f->GetDeclaringClass());
return gRegistry->Add(group);
}
JDWP::ObjectId Dbg::GetMainThreadGroupId() {
ScopedObjectAccess soa(Thread::Current());
- Field* f = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_mainThreadGroup);
- Object* group = f->GetObject(f->GetDeclaringClass());
+ mirror::Field* f = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_mainThreadGroup);
+ mirror::Object* group = f->GetObject(f->GetDeclaringClass());
return gRegistry->Add(group);
}
@@ -1691,7 +1703,7 @@
void Dbg::GetThreads(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>& thread_ids) {
class ThreadListVisitor {
public:
- ThreadListVisitor(const ScopedObjectAccessUnchecked& soa, Object* desired_thread_group,
+ ThreadListVisitor(const ScopedObjectAccessUnchecked& soa, mirror::Object* desired_thread_group,
std::vector<JDWP::ObjectId>& thread_ids)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: soa_(soa), desired_thread_group_(desired_thread_group), thread_ids_(thread_ids) {}
@@ -1708,20 +1720,20 @@
// query all threads, so it's easier if we just don't tell them about this thread.
return;
}
- Object* peer = t->GetPeer();
+ mirror::Object* peer = t->GetPeer();
if (IsInDesiredThreadGroup(peer)) {
thread_ids_.push_back(gRegistry->Add(peer));
}
}
private:
- bool IsInDesiredThreadGroup(Object* peer)
+ bool IsInDesiredThreadGroup(mirror::Object* peer)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// peer might be NULL if the thread is still starting up.
if (peer == NULL) {
// We can't tell the debugger about this thread yet.
// TODO: if we identified threads to the debugger by their Thread*
- // rather than their peer's Object*, we could fix this.
+ // rather than their peer's mirror::Object*, we could fix this.
// Doing so might help us report ZOMBIE threads too.
return false;
}
@@ -1729,17 +1741,17 @@
if (desired_thread_group_ == NULL) {
return true;
}
- Object* group = soa_.DecodeField(WellKnownClasses::java_lang_Thread_group)->GetObject(peer);
+ mirror::Object* group = soa_.DecodeField(WellKnownClasses::java_lang_Thread_group)->GetObject(peer);
return (group == desired_thread_group_);
}
const ScopedObjectAccessUnchecked& soa_;
- Object* const desired_thread_group_;
+ mirror::Object* const desired_thread_group_;
std::vector<JDWP::ObjectId>& thread_ids_;
};
ScopedObjectAccessUnchecked soa(Thread::Current());
- Object* thread_group = gRegistry->Get<Object*>(thread_group_id);
+ mirror::Object* thread_group = gRegistry->Get<mirror::Object*>(thread_group_id);
ThreadListVisitor tlv(soa, thread_group, thread_ids);
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
Runtime::Current()->GetThreadList()->ForEach(ThreadListVisitor::Visit, &tlv);
@@ -1747,16 +1759,17 @@
void Dbg::GetChildThreadGroups(JDWP::ObjectId thread_group_id, std::vector<JDWP::ObjectId>& child_thread_group_ids) {
ScopedObjectAccess soa(Thread::Current());
- Object* thread_group = gRegistry->Get<Object*>(thread_group_id);
+ mirror::Object* thread_group = gRegistry->Get<mirror::Object*>(thread_group_id);
// Get the ArrayList<ThreadGroup> "groups" out of this thread group...
- Field* groups_field = thread_group->GetClass()->FindInstanceField("groups", "Ljava/util/List;");
- Object* groups_array_list = groups_field->GetObject(thread_group);
+ mirror::Field* groups_field = thread_group->GetClass()->FindInstanceField("groups", "Ljava/util/List;");
+ mirror::Object* groups_array_list = groups_field->GetObject(thread_group);
// Get the array and size out of the ArrayList<ThreadGroup>...
- Field* array_field = groups_array_list->GetClass()->FindInstanceField("array", "[Ljava/lang/Object;");
- Field* size_field = groups_array_list->GetClass()->FindInstanceField("size", "I");
- ObjectArray<Object>* groups_array = array_field->GetObject(groups_array_list)->AsObjectArray<Object>();
+ mirror::Field* array_field = groups_array_list->GetClass()->FindInstanceField("array", "[Ljava/lang/Object;");
+ mirror::Field* size_field = groups_array_list->GetClass()->FindInstanceField("size", "I");
+ mirror::ObjectArray<mirror::Object>* groups_array =
+ array_field->GetObject(groups_array_list)->AsObjectArray<mirror::Object>();
const int32_t size = size_field->GetInt(groups_array_list);
// Copy the first 'size' elements out of the array into the result.
@@ -1871,7 +1884,7 @@
ScopedLocalRef<jobject> peer(Thread::Current()->GetJniEnv(), NULL);
{
ScopedObjectAccess soa(Thread::Current());
- peer.reset(soa.AddLocalReference<jobject>(gRegistry->Get<Object*>(thread_id)));
+ peer.reset(soa.AddLocalReference<jobject>(gRegistry->Get<mirror::Object*>(thread_id)));
}
if (peer.get() == NULL) {
return JDWP::ERR_THREAD_NOT_ALIVE;
@@ -1890,7 +1903,7 @@
void Dbg::ResumeThread(JDWP::ObjectId thread_id) {
ScopedObjectAccessUnchecked soa(Thread::Current());
- Object* peer = gRegistry->Get<Object*>(thread_id);
+ mirror::Object* peer = gRegistry->Get<mirror::Object*>(thread_id);
Thread* thread;
{
MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
@@ -1925,21 +1938,21 @@
if (frame_id != GetFrameId()) {
return true; // continue
}
- AbstractMethod* m = GetMethod();
+ mirror::AbstractMethod* m = GetMethod();
if (m->IsNative() || m->IsStatic()) {
this_object = NULL;
} else {
uint16_t reg = DemangleSlot(0, m);
- this_object = reinterpret_cast<Object*>(GetVReg(m, reg, kReferenceVReg));
+ this_object = reinterpret_cast<mirror::Object*>(GetVReg(m, reg, kReferenceVReg));
}
return false;
}
- Object* this_object;
+ mirror::Object* this_object;
JDWP::FrameId frame_id;
};
-static Object* GetThis(Thread* self, AbstractMethod* m, size_t frame_id)
+static mirror::Object* GetThis(Thread* self, mirror::AbstractMethod* m, size_t frame_id)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// TODO: should we return the 'this' we passed through to non-static native methods?
if (m->IsNative() || m->IsStatic()) {
@@ -1989,7 +2002,7 @@
return true; // Not our frame, carry on.
}
// TODO: check that the tag is compatible with the actual type of the slot!
- AbstractMethod* m = GetMethod();
+ mirror::AbstractMethod* m = GetMethod();
uint16_t reg = DemangleSlot(slot_, m);
switch (tag_) {
@@ -2037,7 +2050,7 @@
case JDWP::JT_ARRAY:
{
CHECK_EQ(width_, sizeof(JDWP::ObjectId));
- Object* o = reinterpret_cast<Object*>(GetVReg(m, reg, kReferenceVReg));
+ mirror::Object* o = reinterpret_cast<mirror::Object*>(GetVReg(m, reg, kReferenceVReg));
VLOG(jdwp) << "get array local " << reg << " = " << o;
if (!Runtime::Current()->GetHeap()->IsHeapAddress(o)) {
LOG(FATAL) << "Register " << reg << " expected to hold array: " << o;
@@ -2053,7 +2066,7 @@
case JDWP::JT_THREAD_GROUP:
{
CHECK_EQ(width_, sizeof(JDWP::ObjectId));
- Object* o = reinterpret_cast<Object*>(GetVReg(m, reg, kReferenceVReg));
+ mirror::Object* o = reinterpret_cast<mirror::Object*>(GetVReg(m, reg, kReferenceVReg));
VLOG(jdwp) << "get object local " << reg << " = " << o;
if (!Runtime::Current()->GetHeap()->IsHeapAddress(o)) {
LOG(FATAL) << "Register " << reg << " expected to hold object: " << o;
@@ -2128,7 +2141,7 @@
return true; // Not our frame, carry on.
}
// TODO: check that the tag is compatible with the actual type of the slot!
- AbstractMethod* m = GetMethod();
+ mirror::AbstractMethod* m = GetMethod();
uint16_t reg = DemangleSlot(slot_, m);
switch (tag_) {
@@ -2155,7 +2168,7 @@
case JDWP::JT_STRING:
{
CHECK_EQ(width_, sizeof(JDWP::ObjectId));
- Object* o = gRegistry->Get<Object*>(static_cast<JDWP::ObjectId>(value_));
+ mirror::Object* o = gRegistry->Get<mirror::Object*>(static_cast<JDWP::ObjectId>(value_));
if (o == kInvalidObject) {
UNIMPLEMENTED(FATAL) << "return an error code when given an invalid object to store";
}
@@ -2198,8 +2211,8 @@
visitor.WalkStack();
}
-void Dbg::PostLocationEvent(const AbstractMethod* m, int dex_pc, Object* this_object, int event_flags) {
- Class* c = m->GetDeclaringClass();
+void Dbg::PostLocationEvent(const mirror::AbstractMethod* m, int dex_pc, mirror::Object* this_object, int event_flags) {
+ mirror::Class* c = m->GetDeclaringClass();
JDWP::JdwpLocation location;
location.type_tag = c->IsInterface() ? JDWP::TT_INTERFACE : JDWP::TT_CLASS;
@@ -2220,8 +2233,9 @@
}
void Dbg::PostException(Thread* thread,
- JDWP::FrameId throw_frame_id, AbstractMethod* throw_method, uint32_t throw_dex_pc,
- AbstractMethod* catch_method, uint32_t catch_dex_pc, Throwable* exception) {
+ JDWP::FrameId throw_frame_id, mirror::AbstractMethod* throw_method,
+ uint32_t throw_dex_pc, mirror::AbstractMethod* catch_method,
+ uint32_t catch_dex_pc, mirror::Throwable* exception) {
if (!IsDebuggerActive()) {
return;
}
@@ -2252,7 +2266,7 @@
gJdwpState->PostException(&throw_location, exception_id, exception_class_id, &catch_location, this_id);
}
-void Dbg::PostClassPrepare(Class* c) {
+void Dbg::PostClassPrepare(mirror::Class* c) {
if (!IsDebuggerActive()) {
return;
}
@@ -2271,7 +2285,7 @@
}
size_t frame_id;
- AbstractMethod* m = self->GetCurrentMethod(NULL, &frame_id);
+ mirror::AbstractMethod* m = self->GetCurrentMethod(NULL, &frame_id);
//LOG(INFO) << "UpdateDebugger " << PrettyMethod(m) << "@" << dex_pc << " frame " << frame_id;
if (dex_pc == -1) {
@@ -2375,14 +2389,14 @@
void Dbg::WatchLocation(const JDWP::JdwpLocation* location) {
MutexLock mu(Thread::Current(), *Locks::breakpoint_lock_);
- AbstractMethod* m = FromMethodId(location->method_id);
+ mirror::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(Thread::Current(), *Locks::breakpoint_lock_);
- AbstractMethod* m = FromMethodId(location->method_id);
+ mirror::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) {
VLOG(jdwp) << "Removed breakpoint #" << i << ": " << gBreakpoints[i];
@@ -2428,11 +2442,11 @@
// annotalysis.
bool VisitFrame() NO_THREAD_SAFETY_ANALYSIS {
Locks::breakpoint_lock_->AssertHeld(Thread::Current());
- const AbstractMethod* m = GetMethod();
+ const mirror::AbstractMethod* m = GetMethod();
if (!m->IsRuntimeMethod()) {
++gSingleStepControl.stack_depth;
if (gSingleStepControl.method == NULL) {
- const DexCache* dex_cache = m->GetDeclaringClass()->GetDexCache();
+ const mirror::DexCache* dex_cache = m->GetDeclaringClass()->GetDexCache();
gSingleStepControl.method = m;
gSingleStepControl.line_number = -1;
if (dex_cache != NULL) {
@@ -2497,7 +2511,7 @@
uint32_t last_pc;
};
gSingleStepControl.dex_pcs.clear();
- const AbstractMethod* m = gSingleStepControl.method;
+ const mirror::AbstractMethod* m = gSingleStepControl.method;
if (m->IsNative()) {
gSingleStepControl.line_number = -1;
} else {
@@ -2618,23 +2632,23 @@
}
JDWP::JdwpError status;
- Object* receiver = gRegistry->Get<Object*>(object_id);
+ mirror::Object* receiver = gRegistry->Get<mirror::Object*>(object_id);
if (receiver == kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
- Object* thread = gRegistry->Get<Object*>(thread_id);
+ mirror::Object* thread = gRegistry->Get<mirror::Object*>(thread_id);
if (thread == kInvalidObject) {
return JDWP::ERR_INVALID_OBJECT;
}
// TODO: check that 'thread' is actually a java.lang.Thread!
- Class* c = DecodeClass(class_id, status);
+ mirror::Class* c = DecodeClass(class_id, status);
if (c == NULL) {
return status;
}
- AbstractMethod* m = FromMethodId(method_id);
+ mirror::AbstractMethod* m = FromMethodId(method_id);
if (m->IsStatic() != (receiver == NULL)) {
return JDWP::ERR_INVALID_METHODID;
}
@@ -2739,13 +2753,13 @@
// We can be called while an exception is pending. We need
// to preserve that across the method invocation.
- SirtRef<Throwable> old_exception(soa.Self(), soa.Self()->GetException());
+ SirtRef<mirror::Throwable> old_exception(soa.Self(), soa.Self()->GetException());
soa.Self()->ClearException();
// Translate the method through the vtable, unless the debugger wants to suppress it.
- AbstractMethod* m = pReq->method_;
+ mirror::AbstractMethod* m = pReq->method_;
if ((pReq->options_ & JDWP::INVOKE_NONVIRTUAL) == 0 && pReq->receiver_ != NULL) {
- AbstractMethod* actual_method = pReq->class_->FindVirtualMethodForVirtualOrInterface(pReq->method_);
+ mirror::AbstractMethod* actual_method = pReq->class_->FindVirtualMethodForVirtualOrInterface(pReq->method_);
if (actual_method != m) {
VLOG(jdwp) << "ExecuteMethod translated " << PrettyMethod(m) << " to " << PrettyMethod(actual_method);
m = actual_method;
@@ -2764,7 +2778,7 @@
pReq->exception = gRegistry->Add(soa.Self()->GetException());
pReq->result_tag = BasicTagFromDescriptor(MethodHelper(m).GetShorty());
if (pReq->exception != 0) {
- Object* exc = soa.Self()->GetException();
+ mirror::Object* exc = soa.Self()->GetException();
VLOG(jdwp) << " JDWP invocation returning with exception=" << exc << " " << PrettyTypeOf(exc);
soa.Self()->ClearException();
pReq->result_value.SetJ(0);
@@ -2801,7 +2815,7 @@
* throwing exceptions) we really want to do the registration late.
*/
void Dbg::RegisterObjectId(JDWP::ObjectId id) {
- gRegistry->Add(reinterpret_cast<Object*>(id));
+ gRegistry->Add(reinterpret_cast<mirror::Object*>(id));
}
/*
@@ -2949,7 +2963,7 @@
} else {
CHECK(type == CHUNK_TYPE("THCR") || type == CHUNK_TYPE("THNM")) << type;
ScopedObjectAccessUnchecked soa(Thread::Current());
- SirtRef<String> name(soa.Self(), t->GetThreadName(soa));
+ SirtRef<mirror::String> name(soa.Self(), t->GetThreadName(soa));
size_t char_count = (name.get() != NULL) ? name->GetLength() : 0;
const jchar* chars = (name.get() != NULL) ? name->GetCharArray()->GetData() : NULL;
@@ -3239,7 +3253,7 @@
Flush();
}
}
- const Object *obj = (const Object *)start;
+ const mirror::Object* obj = reinterpret_cast<const mirror::Object*>(start);
// Determine the type of this chunk.
// OLD-TODO: if context.merge, see if this chunk is different from the last chunk.
@@ -3282,7 +3296,7 @@
*p_++ = length - 1;
}
- uint8_t ExamineObject(const Object* o, bool is_native_heap)
+ uint8_t ExamineObject(const mirror::Object* o, bool is_native_heap)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
if (o == NULL) {
return HPSG_STATE(SOLIDITY_FREE, 0);
@@ -3300,7 +3314,7 @@
return HPSG_STATE(SOLIDITY_HARD, KIND_NATIVE);
}
- Class* c = o->GetClass();
+ mirror::Class* c = o->GetClass();
if (c == NULL) {
// The object was probably just created but hasn't been initialized yet.
return HPSG_STATE(SOLIDITY_HARD, KIND_OBJECT);
@@ -3416,7 +3430,7 @@
if (depth >= kMaxAllocRecordStackDepth) {
return false;
}
- AbstractMethod* m = GetMethod();
+ mirror::AbstractMethod* m = GetMethod();
if (!m->IsRuntimeMethod()) {
record->stack[depth].method = m;
record->stack[depth].dex_pc = GetDexPc();
@@ -3437,7 +3451,7 @@
size_t depth;
};
-void Dbg::RecordAllocation(Class* type, size_t byte_count) {
+void Dbg::RecordAllocation(mirror::Class* type, size_t byte_count) {
Thread* self = Thread::Current();
CHECK(self != NULL);
@@ -3499,7 +3513,7 @@
<< PrettyClass(record->type);
for (size_t stack_frame = 0; stack_frame < kMaxAllocRecordStackDepth; ++stack_frame) {
- const AbstractMethod* m = record->stack[stack_frame].method;
+ const mirror::AbstractMethod* m = record->stack[stack_frame].method;
if (m == NULL) {
break;
}
@@ -3619,7 +3633,7 @@
MethodHelper mh;
for (size_t i = 0; i < kMaxAllocRecordStackDepth; i++) {
- AbstractMethod* m = record->stack[i].method;
+ mirror::AbstractMethod* m = record->stack[i].method;
if (m != NULL) {
mh.ChangeMethod(m);
class_names.Add(mh.GetDeclaringClassDescriptor());
diff --git a/src/debugger.h b/src/debugger.h
index b34a401..a796349 100644
--- a/src/debugger.h
+++ b/src/debugger.h
@@ -26,10 +26,17 @@
#include <string>
#include "jdwp/jdwp.h"
-#include "object.h"
+#include "jni.h"
+#include "jvalue.h"
+#include "root_visitor.h"
namespace art {
-
+namespace mirror {
+class AbstractMethod;
+class Class;
+class Object;
+class Throwable;
+} // namespace mirror
struct AllocRecord;
class Thread;
@@ -53,10 +60,10 @@
bool invoke_needed_;
/* request */
- Object* receiver_; /* not used for ClassType.InvokeMethod */
- Object* thread_;
- Class* class_;
- AbstractMethod* method_;
+ mirror::Object* receiver_; /* not used for ClassType.InvokeMethod */
+ mirror::Object* thread_;
+ mirror::Class* class_;
+ mirror::AbstractMethod* method_;
uint32_t arg_count_;
uint64_t* arg_values_; /* will be NULL if arg_count_ == 0 */
uint32_t options_;
@@ -118,7 +125,7 @@
static void Exit(int status);
- static void VisitRoots(Heap::RootVisitor* visitor, void* arg);
+ static void VisitRoots(RootVisitor* visitor, void* arg);
/*
* Class, Object, Array
@@ -311,17 +318,19 @@
kMethodEntry = 0x04,
kMethodExit = 0x08,
};
- static void PostLocationEvent(const AbstractMethod* method, int pcOffset, Object* thisPtr, int eventFlags)
+ static void PostLocationEvent(const mirror::AbstractMethod* method, int pcOffset,
+ mirror::Object* thisPtr, int eventFlags)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static void PostException(Thread* thread, JDWP::FrameId throw_frame_id, AbstractMethod* throw_method,
- uint32_t throw_dex_pc, AbstractMethod* catch_method, uint32_t catch_dex_pc,
- Throwable* exception)
+ static void PostException(Thread* thread, JDWP::FrameId throw_frame_id,
+ mirror::AbstractMethod* throw_method,
+ uint32_t throw_dex_pc, mirror::AbstractMethod* catch_method,
+ uint32_t catch_dex_pc, mirror::Throwable* exception)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void PostThreadStart(Thread* t)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void PostThreadDeath(Thread* t)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static void PostClassPrepare(Class* c)
+ static void PostClassPrepare(mirror::Class* c)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void UpdateDebugger(int32_t dex_pc, Thread* self)
@@ -373,12 +382,11 @@
/*
* Recent allocation tracking support.
*/
- static void RecordAllocation(Class* type, size_t byte_count)
+ static void RecordAllocation(mirror::Class* type, size_t byte_count)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void SetAllocTrackingEnabled(bool enabled);
static inline bool IsAllocTrackingEnabled() { return recent_allocation_records_ != NULL; }
- static jbyteArray GetRecentAllocations()
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ static jbyteArray GetRecentAllocations() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void DumpRecentAllocations();
enum HpifWhen {
diff --git a/src/dex2oat.cc b/src/dex2oat.cc
index a2d35e4..bc38bdc 100644
--- a/src/dex2oat.cc
+++ b/src/dex2oat.cc
@@ -27,10 +27,14 @@
#include "base/stringpiece.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
-#include "class_loader.h"
#include "compiler.h"
#include "image_writer.h"
#include "leb128.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/class-inl.h"
+#include "mirror/class_loader.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
#include "oat_writer.h"
#include "object_utils.h"
#include "os.h"
@@ -161,7 +165,7 @@
continue;
}
std::string descriptor(DotToDescriptor(dot.c_str()));
- SirtRef<Class> klass(self, class_linker->FindSystemClass(descriptor.c_str()));
+ SirtRef<mirror::Class> klass(self, class_linker->FindSystemClass(descriptor.c_str()));
if (klass.get() == NULL) {
LOG(WARNING) << "Failed to find class " << descriptor;
Thread::Current()->ClearException();
@@ -173,7 +177,7 @@
// exceptions are resolved by the verifier when there is a catch block in an interested method.
// Do this here so that exception classes appear to have been specified image classes.
std::set<std::pair<uint16_t, const DexFile*> > unresolved_exception_types;
- SirtRef<Class> java_lang_Throwable(self,
+ SirtRef<mirror::Class> java_lang_Throwable(self,
class_linker->FindSystemClass("Ljava/lang/Throwable;"));
do {
unresolved_exception_types.clear();
@@ -185,10 +189,10 @@
it != end; ++it) {
uint16_t exception_type_idx = it->first;
const DexFile* dex_file = it->second;
- DexCache* dex_cache = class_linker->FindDexCache(*dex_file);
- ClassLoader* class_loader = NULL;
- SirtRef<Class> klass(self, class_linker->ResolveType(*dex_file, exception_type_idx,
- dex_cache, class_loader));
+ mirror::DexCache* dex_cache = class_linker->FindDexCache(*dex_file);
+ mirror:: ClassLoader* class_loader = NULL;
+ SirtRef<mirror::Class> klass(self, class_linker->ResolveType(*dex_file, exception_type_idx,
+ dex_cache, class_loader));
if (klass.get() == NULL) {
const DexFile::TypeId& type_id = dex_file->GetTypeId(exception_type_idx);
const char* descriptor = dex_file->GetTypeDescriptor(type_id);
@@ -404,25 +408,25 @@
}
}
- static bool ResolveCatchBlockExceptionsClassVisitor(Class* c, void* arg)
+ static bool ResolveCatchBlockExceptionsClassVisitor(mirror::Class* c, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::set<std::pair<uint16_t, const DexFile*> >* exceptions_to_resolve =
reinterpret_cast<std::set<std::pair<uint16_t, const DexFile*> >*>(arg);
MethodHelper mh;
for (size_t i = 0; i < c->NumVirtualMethods(); ++i) {
- AbstractMethod* m = c->GetVirtualMethod(i);
+ mirror::AbstractMethod* m = c->GetVirtualMethod(i);
mh.ChangeMethod(m);
ResolveExceptionsForMethod(&mh, *exceptions_to_resolve);
}
for (size_t i = 0; i < c->NumDirectMethods(); ++i) {
- AbstractMethod* m = c->GetDirectMethod(i);
+ mirror::AbstractMethod* m = c->GetDirectMethod(i);
mh.ChangeMethod(m);
ResolveExceptionsForMethod(&mh, *exceptions_to_resolve);
}
return true;
}
- static bool RecordImageClassesVisitor(Class* klass, void* arg)
+ static bool RecordImageClassesVisitor(mirror::Class* klass, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::set<std::string>* image_classes = reinterpret_cast<std::set<std::string>*>(arg);
if (klass->IsArrayClass() || klass->IsPrimitive()) {
diff --git a/src/dex_file.cc b/src/dex_file.cc
index 7398616..e67e767 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -30,7 +30,10 @@
#include "dex_file_verifier.h"
#include "globals.h"
#include "leb128.h"
-#include "object.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/field.h"
+#include "mirror/field-inl.h"
+#include "mirror/string.h"
#include "os.h"
#include "safe_map.h"
#include "thread.h"
@@ -94,6 +97,14 @@
return DexFile::OpenFile(filename, location, true);
}
+int DexFile::GetPermissions() const {
+ if (mem_map_.get() == NULL) {
+ return 0;
+ } else {
+ return mem_map_->GetProtect();
+ }
+}
+
const DexFile* DexFile::OpenFile(const std::string& filename,
const std::string& location,
bool verify) {
@@ -146,7 +157,6 @@
const char* DexFile::kClassesDex = "classes.dex";
-// Open classes.dex from within a .zip, .jar, .apk, ...
const DexFile* DexFile::OpenZip(const std::string& filename,
const std::string& location) {
UniquePtr<ZipArchive> zip_archive(ZipArchive::Open(filename));
@@ -157,6 +167,16 @@
return DexFile::Open(*zip_archive.get(), location);
}
+const DexFile* DexFile::OpenMemory(const std::string& location,
+ uint32_t location_checksum,
+ MemMap* mem_map) {
+ return OpenMemory(mem_map->Begin(),
+ mem_map->Size(),
+ location,
+ location_checksum,
+ mem_map);
+}
+
const DexFile* DexFile::Open(const ZipArchive& zip_archive, const std::string& location) {
CHECK(!location.empty());
UniquePtr<ZipEntry> zip_entry(zip_archive.Find(kClassesDex));
@@ -584,7 +604,7 @@
return descriptor;
}
-int32_t DexFile::GetLineNumFromPC(const AbstractMethod* method, uint32_t rel_pc) const {
+int32_t DexFile::GetLineNumFromPC(const mirror::AbstractMethod* method, uint32_t rel_pc) const {
// For native method, lineno should be -2 to indicate it is native. Note that
// "line number == -2" is how libcore tells from StackTraceElement.
if (method->GetCodeItemOffset() == 0) {
@@ -601,6 +621,12 @@
return context.line_num_;
}
+const DexFile::TryItem* DexFile::GetTryItems(const CodeItem& code_item, uint32_t offset) {
+ const uint16_t* insns_end_ = &code_item.insns_[code_item.insns_size_in_code_units_];
+ return reinterpret_cast<const TryItem*>
+ (RoundUp(reinterpret_cast<uint32_t>(insns_end_), 4)) + offset;
+}
+
int32_t DexFile::FindCatchHandlerOffset(const CodeItem &code_item, int32_t tries_size,
uint32_t address) {
// Note: Signed type is important for max and min.
@@ -900,8 +926,8 @@
}
EncodedStaticFieldValueIterator::EncodedStaticFieldValueIterator(const DexFile& dex_file,
- DexCache* dex_cache,
- ClassLoader* class_loader,
+ mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader,
ClassLinker* linker,
const DexFile::ClassDef& class_def)
: dex_file_(dex_file), dex_cache_(dex_cache), class_loader_(class_loader), linker_(linker),
@@ -976,7 +1002,7 @@
ptr_ += width;
}
-void EncodedStaticFieldValueIterator::ReadValueToField(Field* field) const {
+void EncodedStaticFieldValueIterator::ReadValueToField(mirror::Field* field) const {
switch (type_) {
case kBoolean: field->SetBoolean(field->GetDeclaringClass(), jval_.z); break;
case kByte: field->SetByte(field->GetDeclaringClass(), jval_.b); break;
@@ -988,12 +1014,12 @@
case kDouble: field->SetDouble(field->GetDeclaringClass(), jval_.d); break;
case kNull: field->SetObject(field->GetDeclaringClass(), NULL); break;
case kString: {
- String* resolved = linker_->ResolveString(dex_file_, jval_.i, dex_cache_);
+ mirror::String* resolved = linker_->ResolveString(dex_file_, jval_.i, dex_cache_);
field->SetObject(field->GetDeclaringClass(), resolved);
break;
}
case kType: {
- Class* resolved = linker_->ResolveType(dex_file_, jval_.i, dex_cache_, class_loader_);
+ mirror::Class* resolved = linker_->ResolveType(dex_file_, jval_.i, dex_cache_, class_loader_);
field->SetObject(field->GetDeclaringClass(), resolved);
break;
}
diff --git a/src/dex_file.h b/src/dex_file.h
index 184d950..14b4ba0 100644
--- a/src/dex_file.h
+++ b/src/dex_file.h
@@ -29,10 +29,16 @@
#include "modifiers.h"
#include "safe_map.h"
#include "UniquePtr.h"
-#include "utils.h"
namespace art {
+namespace mirror {
+class AbstractMethod;
+class ClassLoader;
+class DexCache;
+class Field;
+} // namespace mirror
+class ClassLinker;
class ZipArchive;
// TODO: move all of the macro functionality into the DexCache class.
@@ -675,11 +681,7 @@
}
}
- static const TryItem* GetTryItems(const CodeItem& code_item, uint32_t offset) {
- const uint16_t* insns_end_ = &code_item.insns_[code_item.insns_size_in_code_units_];
- return reinterpret_cast<const TryItem*>
- (RoundUp(reinterpret_cast<uint32_t>(insns_end_), 4)) + offset;
- }
+ static const TryItem* GetTryItems(const CodeItem& code_item, uint32_t offset);
// Get the base of the encoded data for the given DexCode.
static const byte* GetCatchHandlerData(const CodeItem& code_item, uint32_t offset) {
@@ -775,7 +777,7 @@
// Returns -2 for native methods (as expected in exception traces).
//
// This is used by runtime; therefore use art::Method not art::DexFile::Method.
- int32_t GetLineNumFromPC(const AbstractMethod* method, uint32_t rel_pc) const
+ int32_t GetLineNumFromPC(const mirror::AbstractMethod* method, uint32_t rel_pc) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void DecodeDebugInfo(const CodeItem* code_item, bool is_static, uint32_t method_idx,
@@ -790,13 +792,7 @@
}
}
- int GetPermissions() const {
- if (mem_map_.get() == NULL) {
- return 0;
- } else {
- return mem_map_->GetProtect();
- }
- }
+ int GetPermissions() const;
private:
// Opens a .dex file
@@ -811,13 +807,7 @@
// Opens a .dex file at the given address backed by a MemMap
static const DexFile* OpenMemory(const std::string& location,
uint32_t location_checksum,
- MemMap* mem_map) {
- return OpenMemory(mem_map->Begin(),
- mem_map->Size(),
- location,
- location_checksum,
- mem_map);
- }
+ MemMap* mem_map);
// Opens a .dex file at the given address, optionally backed by a MemMap
static const DexFile* OpenMemory(const byte* dex_file,
@@ -1116,19 +1106,14 @@
DISALLOW_IMPLICIT_CONSTRUCTORS(ClassDataItemIterator);
};
-class ClassLinker;
-class ClassLoader;
-class DexCache;
-class Field;
-
class EncodedStaticFieldValueIterator {
public:
- EncodedStaticFieldValueIterator(const DexFile& dex_file, DexCache* dex_cache, ClassLoader* class_loader,
+ EncodedStaticFieldValueIterator(const DexFile& dex_file, mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader,
ClassLinker* linker, const DexFile::ClassDef& class_def)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void ReadValueToField(Field* field) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void ReadValueToField(mirror::Field* field) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool HasNext() { return pos_ < array_size_; }
@@ -1158,14 +1143,14 @@
static const byte kEncodedValueArgShift = 5;
const DexFile& dex_file_;
- DexCache* dex_cache_; // dex cache to resolve literal objects
- ClassLoader* class_loader_; // ClassLoader to resolve types
- ClassLinker* linker_; // linker to resolve literal objects
- size_t array_size_; // size of array
- size_t pos_; // current position
- const byte* ptr_; // pointer into encoded data array
- ValueType type_; // type of current encoded value
- jvalue jval_; // value of current encoded value
+ mirror::DexCache* dex_cache_; // Dex cache to resolve literal objects.
+ mirror::ClassLoader* class_loader_; // ClassLoader to resolve types.
+ ClassLinker* linker_; // Linker to resolve literal objects.
+ size_t array_size_; // Size of array.
+ size_t pos_; // Current position.
+ const byte* ptr_; // Pointer into encoded data array.
+ ValueType type_; // Type of current encoded value.
+ jvalue jval_; // Value of current encoded value.
DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedStaticFieldValueIterator);
};
std::ostream& operator<<(std::ostream& os, const EncodedStaticFieldValueIterator::ValueType& code);
diff --git a/src/dex_file_verifier.cc b/src/dex_file_verifier.cc
index 83ef31a..2f9054e 100644
--- a/src/dex_file_verifier.cc
+++ b/src/dex_file_verifier.cc
@@ -18,9 +18,10 @@
#include "base/stringprintf.h"
#include "leb128.h"
-#include "object.h"
#include "safe_map.h"
#include "UniquePtr.h"
+#include "utf.h"
+#include "utils.h"
#include "zip_archive.h"
namespace art {
diff --git a/src/dex_instruction.cc b/src/dex_instruction.cc
index d3aa238..55f6eca 100644
--- a/src/dex_instruction.cc
+++ b/src/dex_instruction.cc
@@ -17,6 +17,7 @@
#include "dex_instruction.h"
#include "dex_file.h"
+#include "utils.h"
#include <iomanip>
namespace art {
diff --git a/src/exception_test.cc b/src/exception_test.cc
index 58e6533..240bf95 100644
--- a/src/exception_test.cc
+++ b/src/exception_test.cc
@@ -18,6 +18,8 @@
#include "common_test.h"
#include "dex_file.h"
#include "gtest/gtest.h"
+#include "mirror/object_array-inl.h"
+#include "mirror/stack_trace_element.h"
#include "runtime.h"
#include "scoped_thread_state_change.h"
#include "sirt_ref.h"
@@ -32,8 +34,8 @@
CommonTest::SetUp();
ScopedObjectAccess soa(Thread::Current());
- SirtRef<ClassLoader> class_loader(soa.Self(),
- soa.Decode<ClassLoader*>(LoadDex("ExceptionHandle")));
+ SirtRef<mirror::ClassLoader> class_loader(soa.Self(),
+ soa.Decode<mirror::ClassLoader*>(LoadDex("ExceptionHandle")));
my_klass_ = class_linker_->FindClass("LExceptionHandle;", class_loader.get());
ASSERT_TRUE(my_klass_ != NULL);
class_linker_->EnsureInitialized(my_klass_, false, true);
@@ -90,11 +92,11 @@
std::vector<uint16_t> fake_vmap_table_data_;
std::vector<uint8_t> fake_gc_map_;
- AbstractMethod* method_f_;
- AbstractMethod* method_g_;
+ mirror::AbstractMethod* method_f_;
+ mirror::AbstractMethod* method_g_;
private:
- Class* my_klass_;
+ mirror::Class* my_klass_;
};
TEST_F(ExceptionTest, FindCatchHandler) {
@@ -193,8 +195,8 @@
ASSERT_TRUE(internal != NULL);
jobjectArray ste_array = Thread::InternalStackTraceToStackTraceElementArray(env, internal);
ASSERT_TRUE(ste_array != NULL);
- ObjectArray<StackTraceElement>* trace_array =
- soa.Decode<ObjectArray<StackTraceElement>*>(ste_array);
+ mirror::ObjectArray<mirror::StackTraceElement>* trace_array =
+ soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>*>(ste_array);
ASSERT_TRUE(trace_array != NULL);
ASSERT_TRUE(trace_array->Get(0) != NULL);
diff --git a/src/gc/atomic_stack.h b/src/gc/atomic_stack.h
index cd1781d..0197bce 100644
--- a/src/gc/atomic_stack.h
+++ b/src/gc/atomic_stack.h
@@ -101,11 +101,11 @@
}
T* Begin() {
- return const_cast<Object**>(begin_ + front_index_);
+ return const_cast<mirror::Object**>(begin_ + front_index_);
}
T* End() {
- return const_cast<Object**>(begin_ + back_index_);
+ return const_cast<mirror::Object**>(begin_ + back_index_);
}
size_t Capacity() const {
@@ -159,6 +159,8 @@
DISALLOW_COPY_AND_ASSIGN(AtomicStack);
};
+typedef AtomicStack<mirror::Object*> ObjectStack;
+
} // namespace art
#endif // ART_SRC_MARK_STACK_H_
diff --git a/src/gc/card_table-inl.h b/src/gc/card_table-inl.h
new file mode 100644
index 0000000..13590b7
--- /dev/null
+++ b/src/gc/card_table-inl.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_GC_CARDTABLE_INL_H_
+#define ART_SRC_GC_CARDTABLE_INL_H_
+
+#include "base/logging.h"
+#include "card_table.h"
+#include "cutils/atomic-inline.h"
+#include "space_bitmap.h"
+#include "utils.h"
+
+namespace art {
+
+static inline bool byte_cas(byte old_value, byte new_value, byte* address) {
+ // Little endian means most significant byte is on the left.
+ const size_t shift = reinterpret_cast<uintptr_t>(address) % sizeof(uintptr_t);
+ // Align the address down.
+ address -= shift;
+ int32_t* word_address = reinterpret_cast<int32_t*>(address);
+ // Word with the byte we are trying to cas cleared.
+ const int32_t cur_word = *word_address & ~(0xFF << shift);
+ const int32_t old_word = cur_word | (static_cast<int32_t>(old_value) << shift);
+ const int32_t new_word = cur_word | (static_cast<int32_t>(new_value) << shift);
+ bool success = android_atomic_cas(old_word, new_word, word_address) == 0;
+ return success;
+}
+
+template <typename Visitor, typename FingerVisitor>
+inline void CardTable::Scan(SpaceBitmap* bitmap, byte* scan_begin, byte* scan_end,
+ const Visitor& visitor, const FingerVisitor& finger_visitor,
+ const byte minimum_age) const {
+ DCHECK(bitmap->HasAddress(scan_begin));
+ DCHECK(bitmap->HasAddress(scan_end - 1)); // scan_end is the byte after the last byte we scan.
+ byte* card_cur = CardFromAddr(scan_begin);
+ byte* card_end = CardFromAddr(scan_end);
+ CheckCardValid(card_cur);
+ CheckCardValid(card_end);
+
+ // Handle any unaligned cards at the start.
+ while (!IsAligned<sizeof(word)>(card_cur) && card_cur < card_end) {
+ if (*card_cur >= minimum_age) {
+ uintptr_t start = reinterpret_cast<uintptr_t>(AddrFromCard(card_cur));
+ uintptr_t end = start + kCardSize;
+ bitmap->VisitMarkedRange(start, end, visitor, finger_visitor);
+ }
+ ++card_cur;
+ }
+
+ byte* aligned_end = card_end -
+ (reinterpret_cast<uintptr_t>(card_end) & (sizeof(uintptr_t) - 1));
+
+ // Now we have the words, we can send these to be processed in parallel.
+ uintptr_t* word_cur = reinterpret_cast<uintptr_t*>(card_cur);
+ uintptr_t* word_end = reinterpret_cast<uintptr_t*>(aligned_end);
+
+ // TODO: Parallelize
+ while (word_cur < word_end) {
+ // Find the first dirty card.
+ while (*word_cur == 0 && word_cur < word_end) {
+ word_cur++;
+ }
+ if (word_cur >= word_end) {
+ break;
+ }
+ uintptr_t start_word = *word_cur;
+ for (size_t i = 0; i < sizeof(uintptr_t); ++i) {
+ if ((start_word & 0xFF) >= minimum_age) {
+ byte* card = reinterpret_cast<byte*>(word_cur) + i;
+ const byte card_byte = *card;
+ DCHECK(card_byte == (start_word & 0xFF) || card_byte == kCardDirty)
+ << "card " << static_cast<size_t>(card_byte) << " word " << (start_word & 0xFF);
+ uintptr_t start = reinterpret_cast<uintptr_t>(AddrFromCard(card));
+ uintptr_t end = start + kCardSize;
+ bitmap->VisitMarkedRange(start, end, visitor, finger_visitor);
+ }
+ start_word >>= 8;
+ }
+ ++word_cur;
+ }
+
+ // Handle any unaligned cards at the end.
+ card_cur = reinterpret_cast<byte*>(word_end);
+ while (card_cur < card_end) {
+ if (*card_cur >= minimum_age) {
+ uintptr_t start = reinterpret_cast<uintptr_t>(AddrFromCard(card_cur));
+ uintptr_t end = start + kCardSize;
+ bitmap->VisitMarkedRange(start, end, visitor, finger_visitor);
+ }
+ ++card_cur;
+ }
+}
+
+/*
+ * Visitor is expected to take in a card and return the new value. When a value is modified, the
+ * modify visitor is called.
+ * visitor: The visitor which modifies the cards. Returns the new value for a card given an old
+ * value.
+ * modified: Whenever the visitor modifies a card, this visitor is called on the card. Enables
+ * us to know which cards got cleared.
+ */
+template <typename Visitor, typename ModifiedVisitor>
+inline void CardTable::ModifyCardsAtomic(byte* scan_begin, byte* scan_end, const Visitor& visitor,
+ const ModifiedVisitor& modified) {
+ byte* card_cur = CardFromAddr(scan_begin);
+ byte* card_end = CardFromAddr(scan_end);
+ CheckCardValid(card_cur);
+ CheckCardValid(card_end);
+
+ // Handle any unaligned cards at the start.
+ while (!IsAligned<sizeof(word)>(card_cur) && card_cur < card_end) {
+ byte expected, new_value;
+ do {
+ expected = *card_cur;
+ new_value = visitor(expected);
+ } while (expected != new_value && UNLIKELY(!byte_cas(expected, new_value, card_cur)));
+ if (expected != new_value) {
+ modified(card_cur, expected, new_value);
+ }
+ ++card_cur;
+ }
+
+ // Handle unaligned cards at the end.
+ while (!IsAligned<sizeof(word)>(card_end) && card_end > card_cur) {
+ --card_end;
+ byte expected, new_value;
+ do {
+ expected = *card_end;
+ new_value = visitor(expected);
+ } while (expected != new_value && UNLIKELY(!byte_cas(expected, new_value, card_end)));
+ if (expected != new_value) {
+ modified(card_cur, expected, new_value);
+ }
+ }
+
+ // Now we have the words, we can process words in parallel.
+ uintptr_t* word_cur = reinterpret_cast<uintptr_t*>(card_cur);
+ uintptr_t* word_end = reinterpret_cast<uintptr_t*>(card_end);
+ uintptr_t expected_word;
+ uintptr_t new_word;
+
+ // TODO: Parallelize.
+ while (word_cur < word_end) {
+ while ((expected_word = *word_cur) != 0) {
+ new_word =
+ (visitor((expected_word >> 0) & 0xFF) << 0) |
+ (visitor((expected_word >> 8) & 0xFF) << 8) |
+ (visitor((expected_word >> 16) & 0xFF) << 16) |
+ (visitor((expected_word >> 24) & 0xFF) << 24);
+ if (new_word == expected_word) {
+ // No need to do a cas.
+ break;
+ }
+ if (LIKELY(android_atomic_cas(expected_word, new_word,
+ reinterpret_cast<int32_t*>(word_cur)) == 0)) {
+ for (size_t i = 0; i < sizeof(uintptr_t); ++i) {
+ const byte expected_byte = (expected_word >> (8 * i)) & 0xFF;
+ const byte new_byte = (new_word >> (8 * i)) & 0xFF;
+ if (expected_byte != new_byte) {
+ modified(reinterpret_cast<byte*>(word_cur) + i, expected_byte, new_byte);
+ }
+ }
+ break;
+ }
+ }
+ ++word_cur;
+ }
+}
+
+inline void* CardTable::AddrFromCard(const byte *card_addr) const {
+ DCHECK(IsValidCard(card_addr))
+ << " card_addr: " << reinterpret_cast<const void*>(card_addr)
+ << " begin: " << reinterpret_cast<void*>(mem_map_->Begin() + offset_)
+ << " end: " << reinterpret_cast<void*>(mem_map_->End());
+ uintptr_t offset = card_addr - biased_begin_;
+ return reinterpret_cast<void*>(offset << kCardShift);
+}
+
+inline byte* CardTable::CardFromAddr(const void *addr) const {
+ byte *card_addr = biased_begin_ + (reinterpret_cast<uintptr_t>(addr) >> kCardShift);
+ // Sanity check the caller was asking for address covered by the card table
+ DCHECK(IsValidCard(card_addr)) << "addr: " << addr
+ << " card_addr: " << reinterpret_cast<void*>(card_addr);
+ return card_addr;
+}
+
+inline void CardTable::CheckCardValid(byte* card) const {
+ DCHECK(IsValidCard(card))
+ << " card_addr: " << reinterpret_cast<const void*>(card)
+ << " begin: " << reinterpret_cast<void*>(mem_map_->Begin() + offset_)
+ << " end: " << reinterpret_cast<void*>(mem_map_->End());
+}
+
+} // namespace art
+
+#endif // ART_SRC_GC_CARDTABLE_INL_H_
diff --git a/src/gc/card_table.cc b/src/gc/card_table.cc
index f27777b..4331270 100644
--- a/src/gc/card_table.cc
+++ b/src/gc/card_table.cc
@@ -19,6 +19,7 @@
#include <dynamic_annotations.h>
#include "base/logging.h"
+#include "gc/card_table-inl.h"
#include "heap.h"
#include "heap_bitmap.h"
#include "runtime.h"
diff --git a/src/gc/card_table.h b/src/gc/card_table.h
index 8f1bc92..842fcc3 100644
--- a/src/gc/card_table.h
+++ b/src/gc/card_table.h
@@ -17,19 +17,18 @@
#ifndef ART_SRC_GC_CARDTABLE_H_
#define ART_SRC_GC_CARDTABLE_H_
-#include "base/logging.h"
#include "globals.h"
+#include "locks.h"
#include "mem_map.h"
-#include "space_bitmap.h"
#include "UniquePtr.h"
-#include "utils.h"
namespace art {
-
+namespace mirror {
+class Object;
+} // namespace mirror
class Heap;
class ContinuousSpace;
class SpaceBitmap;
-class Object;
// Maintain a card table from the the write barrier. All writes of
// non-NULL values to heap addresses should go through an entry in
@@ -50,12 +49,12 @@
}
// Is the object on a dirty card?
- bool IsDirty(const Object* obj) const {
+ bool IsDirty(const mirror::Object* obj) const {
return GetCard(obj) == kCardDirty;
}
// Return the state of the card at an address.
- byte GetCard(const Object* obj) const {
+ byte GetCard(const mirror::Object* obj) const {
return *CardFromAddr(obj);
}
@@ -88,71 +87,7 @@
*/
template <typename Visitor, typename ModifiedVisitor>
void ModifyCardsAtomic(byte* scan_begin, byte* scan_end, const Visitor& visitor,
- const ModifiedVisitor& modified = VoidFunctor()) {
- byte* card_cur = CardFromAddr(scan_begin);
- byte* card_end = CardFromAddr(scan_end);
- CheckCardValid(card_cur);
- CheckCardValid(card_end);
-
- // Handle any unaligned cards at the start.
- while (!IsAligned<sizeof(word)>(card_cur) && card_cur < card_end) {
- byte expected, new_value;
- do {
- expected = *card_cur;
- new_value = visitor(expected);
- } while (expected != new_value && UNLIKELY(byte_cas(expected, new_value, card_cur) != 0));
- if (expected != new_value) {
- modified(card_cur, expected, new_value);
- }
- ++card_cur;
- }
-
- // Handle unaligned cards at the end.
- while (!IsAligned<sizeof(word)>(card_end) && card_end > card_cur) {
- --card_end;
- byte expected, new_value;
- do {
- expected = *card_end;
- new_value = visitor(expected);
- } while (expected != new_value && UNLIKELY(byte_cas(expected, new_value, card_end) != 0));
- if (expected != new_value) {
- modified(card_cur, expected, new_value);
- }
- }
-
- // Now we have the words, we can process words in parallel.
- uintptr_t* word_cur = reinterpret_cast<uintptr_t*>(card_cur);
- uintptr_t* word_end = reinterpret_cast<uintptr_t*>(card_end);
- uintptr_t expected_word;
- uintptr_t new_word;
-
- // TODO: Parallelize.
- while (word_cur < word_end) {
- while ((expected_word = *word_cur) != 0) {
- new_word =
- (visitor((expected_word >> 0) & 0xFF) << 0) |
- (visitor((expected_word >> 8) & 0xFF) << 8) |
- (visitor((expected_word >> 16) & 0xFF) << 16) |
- (visitor((expected_word >> 24) & 0xFF) << 24);
- if (new_word == expected_word) {
- // No need to do a cas.
- break;
- }
- if (LIKELY(android_atomic_cas(expected_word, new_word,
- reinterpret_cast<int32_t*>(word_cur)) == 0)) {
- for (size_t i = 0; i < sizeof(uintptr_t); ++i) {
- const byte expected_byte = (expected_word >> (8 * i)) & 0xFF;
- const byte new_byte = (new_word >> (8 * i)) & 0xFF;
- if (expected_byte != new_byte) {
- modified(reinterpret_cast<byte*>(word_cur) + i, expected_byte, new_byte);
- }
- }
- break;
- }
- }
- ++word_cur;
- }
- }
+ const ModifiedVisitor& modified);
// For every dirty at least minumum age between begin and end invoke the visitor with the
// specified argument.
@@ -161,67 +96,7 @@
const Visitor& visitor, const FingerVisitor& finger_visitor,
const byte minimum_age = kCardDirty) const
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(bitmap->HasAddress(scan_begin));
- DCHECK(bitmap->HasAddress(scan_end - 1)); // scan_end is the byte after the last byte we scan.
- byte* card_cur = CardFromAddr(scan_begin);
- byte* card_end = CardFromAddr(scan_end);
- CheckCardValid(card_cur);
- CheckCardValid(card_end);
-
- // Handle any unaligned cards at the start.
- while (!IsAligned<sizeof(word)>(card_cur) && card_cur < card_end) {
- if (*card_cur >= minimum_age) {
- uintptr_t start = reinterpret_cast<uintptr_t>(AddrFromCard(card_cur));
- uintptr_t end = start + kCardSize;
- bitmap->VisitMarkedRange(start, end, visitor, finger_visitor);
- }
- ++card_cur;
- }
-
- byte* aligned_end = card_end -
- (reinterpret_cast<uintptr_t>(card_end) & (sizeof(uintptr_t) - 1));
-
- // Now we have the words, we can send these to be processed in parallel.
- uintptr_t* word_cur = reinterpret_cast<uintptr_t*>(card_cur);
- uintptr_t* word_end = reinterpret_cast<uintptr_t*>(aligned_end);
-
- // TODO: Parallelize
- while (word_cur < word_end) {
- // Find the first dirty card.
- while (*word_cur == 0 && word_cur < word_end) {
- word_cur++;
- }
- if (word_cur >= word_end) {
- break;
- }
- uintptr_t start_word = *word_cur;
- for (size_t i = 0; i < sizeof(uintptr_t); ++i) {
- if ((start_word & 0xFF) >= minimum_age) {
- byte* card = reinterpret_cast<byte*>(word_cur) + i;
- const byte card_byte = *card;
- DCHECK(card_byte == (start_word & 0xFF) || card_byte == kCardDirty)
- << "card " << static_cast<size_t>(card_byte) << " word " << (start_word & 0xFF);
- uintptr_t start = reinterpret_cast<uintptr_t>(AddrFromCard(card));
- uintptr_t end = start + kCardSize;
- bitmap->VisitMarkedRange(start, end, visitor, finger_visitor);
- }
- start_word >>= 8;
- }
- ++word_cur;
- }
-
- // Handle any unaligned cards at the end.
- card_cur = reinterpret_cast<byte*>(word_end);
- while (card_cur < card_end) {
- if (*card_cur >= minimum_age) {
- uintptr_t start = reinterpret_cast<uintptr_t>(AddrFromCard(card_cur));
- uintptr_t end = start + kCardSize;
- bitmap->VisitMarkedRange(start, end, visitor, finger_visitor);
- }
- ++card_cur;
- }
- }
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Assertion used to check the given address is covered by the card table
void CheckAddrIsInCardTable(const byte* addr) const;
@@ -233,40 +108,14 @@
void ClearSpaceCards(ContinuousSpace* space);
// Returns the first address in the heap which maps to this card.
- void* AddrFromCard(const byte *card_addr) const {
- DCHECK(IsValidCard(card_addr))
- << " card_addr: " << reinterpret_cast<const void*>(card_addr)
- << " begin: " << reinterpret_cast<void*>(mem_map_->Begin() + offset_)
- << " end: " << reinterpret_cast<void*>(mem_map_->End());
- uintptr_t offset = card_addr - biased_begin_;
- return reinterpret_cast<void*>(offset << kCardShift);
- }
+ void* AddrFromCard(const byte *card_addr) const;
// Returns the address of the relevant byte in the card table, given an address on the heap.
- byte* CardFromAddr(const void *addr) const {
- byte *card_addr = biased_begin_ + (reinterpret_cast<uintptr_t>(addr) >> kCardShift);
- // Sanity check the caller was asking for address covered by the card table
- DCHECK(IsValidCard(card_addr)) << "addr: " << addr
- << " card_addr: " << reinterpret_cast<void*>(card_addr);
- return card_addr;
- }
+ byte* CardFromAddr(const void *addr) const;
bool AddrIsInCardTable(const void* addr) const;
private:
- static int byte_cas(byte old_value, byte new_value, byte* address) {
- // Little endian means most significant byte is on the left.
- const size_t shift = reinterpret_cast<uintptr_t>(address) % sizeof(uintptr_t);
- // Align the address down.
- address -= shift;
- int32_t* word_address = reinterpret_cast<int32_t*>(address);
- // Word with the byte we are trying to cas cleared.
- const int32_t cur_word = *word_address & ~(0xFF << shift);
- const int32_t old_word = cur_word | (static_cast<int32_t>(old_value) << shift);
- const int32_t new_word = cur_word | (static_cast<int32_t>(new_value) << shift);
- return android_atomic_cas(old_word, new_word, word_address);
- }
-
CardTable(MemMap* begin, byte* biased_begin, size_t offset);
// Returns true iff the card table address is within the bounds of the card table.
@@ -276,12 +125,7 @@
return card_addr >= begin && card_addr < end;
}
- void CheckCardValid(byte* card) const {
- DCHECK(IsValidCard(card))
- << " card_addr: " << reinterpret_cast<const void*>(card)
- << " begin: " << reinterpret_cast<void*>(mem_map_->Begin() + offset_)
- << " end: " << reinterpret_cast<void*>(mem_map_->End());
- }
+ void CheckCardValid(byte* card) const;
// Verifies that all gray objects are on a dirty card.
void VerifyCardTable();
diff --git a/src/gc/garbage_collector.cc b/src/gc/garbage_collector.cc
index bcc7b63..fbcdbaf 100644
--- a/src/gc/garbage_collector.cc
+++ b/src/gc/garbage_collector.cc
@@ -15,6 +15,7 @@
*/
#include "garbage_collector.h"
+#include "thread.h"
#include "thread_list.h"
namespace art {
diff --git a/src/gc/garbage_collector.h b/src/gc/garbage_collector.h
index 9ddf45f..a1014c2 100644
--- a/src/gc/garbage_collector.h
+++ b/src/gc/garbage_collector.h
@@ -14,11 +14,13 @@
* limitations under the License.
*/
-#ifndef ART_SRC_GC_GARBAGE_COLLECTR_H_
-#define ART_SRC_GC_GARBAGE_COLLECTR_H_
+#ifndef ART_SRC_GC_GARBAGE_COLLECTOR_H_
+#define ART_SRC_GC_GARBAGE_COLLECTOR_H_
#include "locks.h"
-#include "utils.h"
+
+#include <stdint.h>
+#include <vector>
namespace art {
@@ -56,7 +58,7 @@
void RegisterPause(uint64_t nano_length);
protected:
- // The initial phase. Done with mutators upaused.
+ // The initial phase. Done without mutators paused.
virtual void InitializePhase() = 0;
// Mark all reachable objects, done concurrently.
@@ -68,7 +70,7 @@
// Called with mutators running.
virtual void ReclaimPhase() = 0;
- // Called after the GC is finished. Done with mutators upaused.
+ // Called after the GC is finished. Done without mutators paused.
virtual void FinishPhase() = 0;
Heap* heap_;
@@ -78,4 +80,4 @@
} // namespace art
-#endif // ART_SRC_GC_GARBAGE_COLLECTR_H_
+#endif // ART_SRC_GC_GARBAGE_COLLECTOR_H_
diff --git a/src/gc/gc_type.h b/src/gc/gc_type.h
new file mode 100644
index 0000000..908f038
--- /dev/null
+++ b/src/gc/gc_type.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_GC_GC_TYPE_H_
+#define ART_SRC_GC_GC_TYPE_H_
+
+namespace art {
+
+// The ordering of the enum matters, it is used to determine which GCs are run first.
+enum GcType {
+ // No Gc
+ kGcTypeNone,
+ // Sticky mark bits "generational" GC.
+ kGcTypeSticky,
+ // Partial GC, over only the alloc space.
+ kGcTypePartial,
+ // Full GC
+ kGcTypeFull,
+ // Number of different Gc types.
+ kGcTypeMax,
+};
+std::ostream& operator<<(std::ostream& os, const GcType& policy);
+
+} // namespace art
+
+#endif // ART_SRC_GC_GC_TYPE_H_
diff --git a/src/gc/heap_bitmap-inl.h b/src/gc/heap_bitmap-inl.h
new file mode 100644
index 0000000..2811183
--- /dev/null
+++ b/src/gc/heap_bitmap-inl.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_GC_HEAP_BITMAP_INL_H_
+#define ART_SRC_GC_HEAP_BITMAP_INL_H_
+
+#include "heap_bitmap.h"
+
+namespace art {
+
+template <typename Visitor>
+inline void HeapBitmap::Visit(const Visitor& visitor) {
+ // TODO: C++0x auto
+ for (Bitmaps::iterator it = bitmaps_.begin(); it != bitmaps_.end(); ++it) {
+ SpaceBitmap* bitmap = *it;
+ bitmap->VisitMarkedRange(bitmap->HeapBegin(), bitmap->HeapLimit(), visitor, VoidFunctor());
+ }
+ large_objects_->Visit(visitor);
+}
+
+} // namespace art
+
+#endif // ART_SRC_GC_HEAP_BITMAP_INL_H_
diff --git a/src/gc/heap_bitmap.h b/src/gc/heap_bitmap.h
index 42c4166..87e0848 100644
--- a/src/gc/heap_bitmap.h
+++ b/src/gc/heap_bitmap.h
@@ -14,96 +14,91 @@
* limitations under the License.
*/
-#ifndef ART_SRC_HEAP_BITMAP_H_
-#define ART_SRC_HEAP_BITMAP_H_
+#ifndef ART_SRC_GC_HEAP_BITMAP_H_
+#define ART_SRC_GC_HEAP_BITMAP_H_
+#include "locks.h"
#include "space_bitmap.h"
namespace art {
- class Heap;
- class SpaceBitmap;
+class Heap;
- class HeapBitmap {
- public:
- bool Test(const Object* obj) SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
- SpaceBitmap* bitmap = GetSpaceBitmap(obj);
- if (LIKELY(bitmap != NULL)) {
- return bitmap->Test(obj);
- } else {
- return large_objects_->Test(obj);
+class HeapBitmap {
+ public:
+ bool Test(const mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
+ SpaceBitmap* bitmap = GetSpaceBitmap(obj);
+ if (LIKELY(bitmap != NULL)) {
+ return bitmap->Test(obj);
+ } else {
+ return large_objects_->Test(obj);
+ }
+ }
+
+ void Clear(const mirror::Object* obj)
+ EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
+ SpaceBitmap* bitmap = GetSpaceBitmap(obj);
+ if (LIKELY(bitmap != NULL)) {
+ bitmap->Clear(obj);
+ } else {
+ large_objects_->Clear(obj);
+ }
+ }
+
+ void Set(const mirror::Object* obj)
+ EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
+ SpaceBitmap* bitmap = GetSpaceBitmap(obj);
+ if (LIKELY(bitmap != NULL)) {
+ bitmap->Set(obj);
+ } else {
+ large_objects_->Set(obj);
+ }
+ }
+
+ SpaceBitmap* GetSpaceBitmap(const mirror::Object* obj) {
+ // TODO: C++0x auto
+ for (Bitmaps::iterator it = bitmaps_.begin(); it != bitmaps_.end(); ++it) {
+ if ((*it)->HasAddress(obj)) {
+ return *it;
}
}
+ return NULL;
+ }
- void Clear(const Object* obj)
- EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
- SpaceBitmap* bitmap = GetSpaceBitmap(obj);
- if (LIKELY(bitmap != NULL)) {
- bitmap->Clear(obj);
- } else {
- large_objects_->Clear(obj);
- }
- }
+ void Walk(SpaceBitmap::Callback* callback, void* arg)
+ SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
- void Set(const Object* obj)
- EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
- SpaceBitmap* bitmap = GetSpaceBitmap(obj);
- if (LIKELY(bitmap != NULL)) {
- bitmap->Set(obj);
- } else {
- large_objects_->Set(obj);
- }
- }
+ template <typename Visitor>
+ void Visit(const Visitor& visitor)
+ EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- SpaceBitmap* GetSpaceBitmap(const Object* obj) {
- // TODO: C++0x auto
- for (Bitmaps::iterator it = bitmaps_.begin(); it != bitmaps_.end(); ++it) {
- if ((*it)->HasAddress(obj)) {
- return *it;
- }
- }
- return NULL;
- }
+ // Find and replace a bitmap pointer, this is used by for the bitmap swapping in the GC.
+ void ReplaceBitmap(SpaceBitmap* old_bitmap, SpaceBitmap* new_bitmap)
+ EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
- void Walk(SpaceBitmap::Callback* callback, void* arg)
- SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
+ HeapBitmap(Heap* heap);
- template <typename Visitor>
- void Visit(const Visitor& visitor)
- EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
- // TODO: C++0x auto
- for (Bitmaps::iterator it = bitmaps_.begin(); it != bitmaps_.end(); ++it) {
- SpaceBitmap* bitmap = *it;
- bitmap->VisitMarkedRange(bitmap->HeapBegin(), bitmap->HeapLimit(), visitor, VoidFunctor());
- }
- large_objects_->Visit(visitor);
- }
+ inline SpaceSetMap* GetLargeObjects() const {
+ return large_objects_;
+ }
- // Find and replace a bitmap pointer, this is used by for the bitmap swapping in the GC.
- void ReplaceBitmap(SpaceBitmap* old_bitmap, SpaceBitmap* new_bitmap)
- EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
+ void SetLargeObjects(SpaceSetMap* large_objects);
- HeapBitmap(Heap* heap);
+ private:
- inline SpaceSetMap* GetLargeObjects() const {
- return large_objects_;
- }
+ const Heap* const heap_;
- void SetLargeObjects(SpaceSetMap* large_objects);
+ void AddSpaceBitmap(SpaceBitmap* bitmap);
- private:
+ typedef std::vector<SpaceBitmap*> Bitmaps;
+ Bitmaps bitmaps_;
- const Heap* const heap_;
+ // Large object sets.
+ SpaceSetMap* large_objects_;
- void AddSpaceBitmap(SpaceBitmap* bitmap);
+ friend class Heap;
+};
- typedef std::vector<SpaceBitmap*> Bitmaps;
- Bitmaps bitmaps_;
-
- // Large object sets.
- SpaceSetMap* large_objects_;
-
- friend class Heap;
- };
} // namespace art
-#endif // ART_SRC_HEAP_BITMAP_H_
+#endif // ART_SRC_GC_HEAP_BITMAP_H_
diff --git a/src/gc/large_object_space.cc b/src/gc/large_object_space.cc
index 1b93e5d..69320fa 100644
--- a/src/gc/large_object_space.cc
+++ b/src/gc/large_object_space.cc
@@ -22,6 +22,7 @@
#include "image.h"
#include "os.h"
#include "space_bitmap.h"
+#include "thread.h"
#include "utils.h"
namespace art {
@@ -58,13 +59,13 @@
return new LargeObjectMapSpace(name);
}
-Object* LargeObjectMapSpace::Alloc(Thread* self, size_t num_bytes) {
+mirror::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());
+ mirror::Object* obj = reinterpret_cast<mirror::Object*>(mem_map->Begin());
large_objects_.push_back(obj);
mem_maps_.Put(obj, mem_map);
size_t allocation_size = mem_map->Size();
@@ -75,7 +76,7 @@
return obj;
}
-size_t LargeObjectMapSpace::Free(Thread* self, Object* ptr) {
+size_t LargeObjectMapSpace::Free(Thread* self, mirror::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";
@@ -88,14 +89,14 @@
return allocation_size;
}
-size_t LargeObjectMapSpace::AllocationSize(const Object* obj) {
+size_t LargeObjectMapSpace::AllocationSize(const mirror::Object* obj) {
MutexLock mu(Thread::Current(), lock_);
- MemMaps::iterator found = mem_maps_.find(const_cast<Object*>(obj));
+ MemMaps::iterator found = mem_maps_.find(const_cast<mirror::Object*>(obj));
CHECK(found != mem_maps_.end()) << "Attempted to get size of a large object which is not live";
return found->second->Size();
}
-size_t LargeObjectSpace::FreeList(Thread* self, size_t num_ptrs, Object** ptrs) {
+size_t LargeObjectSpace::FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) {
size_t total = 0;
for (size_t i = 0; i < num_ptrs; ++i) {
if (kDebugSpaces) {
@@ -115,9 +116,9 @@
}
}
-bool LargeObjectMapSpace::Contains(const Object* obj) const {
+bool LargeObjectMapSpace::Contains(const mirror::Object* obj) const {
MutexLock mu(Thread::Current(), lock_);
- return mem_maps_.find(const_cast<Object*>(obj)) != mem_maps_.end();
+ return mem_maps_.find(const_cast<mirror::Object*>(obj)) != mem_maps_.end();
}
FreeListSpace* FreeListSpace::Create(const std::string& name, byte* requested_begin, size_t size) {
@@ -191,7 +192,7 @@
}
}
-size_t FreeListSpace::Free(Thread* self, Object* obj) {
+size_t FreeListSpace::Free(Thread* self, mirror::Object* obj) {
MutexLock mu(self, lock_);
CHECK(Contains(obj));
// Check adjacent chunks to see if we need to combine.
@@ -220,7 +221,7 @@
return allocation_size;
}
-bool FreeListSpace::Contains(const Object* obj) const {
+bool FreeListSpace::Contains(const mirror::Object* obj) const {
return mem_map_->HasAddress(obj);
}
@@ -228,13 +229,13 @@
return chunk + chunk->GetSize() / kAlignment;
}
-size_t FreeListSpace::AllocationSize(const Object* obj) {
- Chunk* chunk = ChunkFromAddr(const_cast<Object*>(obj));
+size_t FreeListSpace::AllocationSize(const mirror::Object* obj) {
+ Chunk* chunk = ChunkFromAddr(const_cast<mirror::Object*>(obj));
CHECK(!chunk->IsFree());
return chunk->GetSize();
}
-Object* FreeListSpace::Alloc(Thread* self, size_t num_bytes) {
+mirror::Object* FreeListSpace::Alloc(Thread* self, size_t num_bytes) {
MutexLock mu(self, lock_);
num_bytes = RoundUp(num_bytes, kAlignment);
Chunk temp;
@@ -261,7 +262,7 @@
total_objects_allocated_++;
num_bytes_allocated_ += num_bytes;
total_bytes_allocated_ += num_bytes;
- return reinterpret_cast<Object*>(addr);
+ return reinterpret_cast<mirror::Object*>(addr);
}
void FreeListSpace::Dump(std::ostream& os) const{
diff --git a/src/gc/large_object_space.h b/src/gc/large_object_space.h
index 979fce6..c34dbcc 100644
--- a/src/gc/large_object_space.h
+++ b/src/gc/large_object_space.h
@@ -18,8 +18,13 @@
#define ART_SRC_GC_LARGE_OBJECT_SPACE_H_
#include "space.h"
+#include "safe_map.h"
+
+#include <set>
+#include <vector>
namespace art {
+class SpaceSetMap;
class LargeObjectSpace : public DiscontinuousSpace, public AllocSpace {
public:
@@ -64,7 +69,7 @@
return total_objects_allocated_;
}
- size_t FreeList(Thread* self, size_t num_ptrs, Object** ptrs);
+ size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs);
protected:
@@ -90,19 +95,19 @@
static LargeObjectMapSpace* Create(const std::string& name);
// Return the storage space required by obj.
- virtual size_t AllocationSize(const Object* obj);
- virtual Object* Alloc(Thread* self, size_t num_bytes);
- size_t Free(Thread* self, Object* ptr);
+ virtual size_t AllocationSize(const mirror::Object* obj);
+ virtual mirror::Object* Alloc(Thread* self, size_t num_bytes);
+ size_t Free(Thread* self, mirror::Object* ptr);
virtual void Walk(DlMallocSpace::WalkCallback, void* arg);
- virtual bool Contains(const Object* obj) const;
+ virtual bool Contains(const mirror::Object* obj) const;
private:
LargeObjectMapSpace(const std::string& name);
virtual ~LargeObjectMapSpace() {}
// Used to ensure mutual exclusion when the allocation spaces data structures are being modified.
mutable Mutex lock_;
- std::vector<Object*> large_objects_;
- typedef SafeMap<Object*, MemMap*> MemMaps;
+ std::vector<mirror::Object*> large_objects_;
+ typedef SafeMap<mirror::Object*, MemMap*> MemMaps;
MemMaps mem_maps_;
};
@@ -111,10 +116,10 @@
virtual ~FreeListSpace();
static FreeListSpace* Create(const std::string& name, byte* requested_begin, size_t capacity);
- size_t AllocationSize(const Object* obj);
- Object* Alloc(Thread* self, size_t num_bytes);
- size_t Free(Thread* self, Object* obj);
- bool Contains(const Object* obj) const;
+ size_t AllocationSize(const mirror::Object* obj);
+ mirror::Object* Alloc(Thread* self, size_t num_bytes);
+ size_t Free(Thread* self, mirror::Object* obj);
+ bool Contains(const mirror::Object* obj) const;
void Walk(DlMallocSpace::WalkCallback callback, void* arg);
// Address at which the space begins
diff --git a/src/gc/mark_sweep-inl.h b/src/gc/mark_sweep-inl.h
new file mode 100644
index 0000000..7265023
--- /dev/null
+++ b/src/gc/mark_sweep-inl.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_GC_MARK_SWEEP_INL_H_
+#define ART_SRC_GC_MARK_SWEEP_INL_H_
+
+#include "heap.h"
+#include "mirror/class.h"
+#include "mirror/field.h"
+#include "mirror/object_array.h"
+
+namespace art {
+
+template <typename MarkVisitor>
+inline void MarkSweep::ScanObjectVisit(const mirror::Object* obj, const MarkVisitor& visitor) {
+ DCHECK(obj != NULL);
+ if (kIsDebugBuild && !IsMarked(obj)) {
+ heap_->DumpSpaces();
+ LOG(FATAL) << "Scanning unmarked object " << obj;
+ }
+ mirror::Class* klass = obj->GetClass();
+ DCHECK(klass != NULL);
+ if (klass == java_lang_Class_) {
+ DCHECK_EQ(klass->GetClass(), java_lang_Class_);
+ if (kCountScannedTypes) {
+ ++class_count_;
+ }
+ VisitClassReferences(klass, obj, visitor);
+ } else if (klass->IsArrayClass()) {
+ if (kCountScannedTypes) {
+ ++array_count_;
+ }
+ visitor(obj, klass, mirror::Object::ClassOffset(), false);
+ if (klass->IsObjectArrayClass()) {
+ VisitObjectArrayReferences(obj->AsObjectArray<mirror::Object>(), visitor);
+ }
+ } else {
+ if (kCountScannedTypes) {
+ ++other_count_;
+ }
+ VisitOtherReferences(klass, obj, visitor);
+ if (UNLIKELY(klass->IsReferenceClass())) {
+ DelayReferenceReferent(const_cast<mirror::Object*>(obj));
+ }
+ }
+}
+
+template <typename Visitor>
+inline void MarkSweep::VisitObjectReferences(const mirror::Object* obj, const Visitor& visitor)
+ SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_,
+ Locks::mutator_lock_) {
+ DCHECK(obj != NULL);
+ DCHECK(obj->GetClass() != NULL);
+
+ mirror::Class* klass = obj->GetClass();
+ DCHECK(klass != NULL);
+ if (klass == mirror::Class::GetJavaLangClass()) {
+ DCHECK_EQ(klass->GetClass(), mirror::Class::GetJavaLangClass());
+ VisitClassReferences(klass, obj, visitor);
+ } else {
+ if (klass->IsArrayClass()) {
+ visitor(obj, klass, mirror::Object::ClassOffset(), false);
+ if (klass->IsObjectArrayClass()) {
+ VisitObjectArrayReferences(obj->AsObjectArray<mirror::Object>(), visitor);
+ }
+ } else {
+ VisitOtherReferences(klass, obj, visitor);
+ }
+ }
+}
+
+template <typename Visitor>
+inline void MarkSweep::VisitInstanceFieldsReferences(const mirror::Class* klass,
+ const mirror::Object* obj,
+ const Visitor& visitor)
+ SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
+ DCHECK(obj != NULL);
+ DCHECK(klass != NULL);
+ VisitFieldsReferences(obj, klass->GetReferenceInstanceOffsets(), false, visitor);
+}
+
+template <typename Visitor>
+inline void MarkSweep::VisitClassReferences(const mirror::Class* klass, const mirror::Object* obj,
+ const Visitor& visitor)
+ SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
+ VisitInstanceFieldsReferences(klass, obj, visitor);
+ VisitStaticFieldsReferences(obj->AsClass(), visitor);
+}
+
+template <typename Visitor>
+inline void MarkSweep::VisitStaticFieldsReferences(const mirror::Class* klass,
+ const Visitor& visitor)
+ SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
+ DCHECK(klass != NULL);
+ VisitFieldsReferences(klass, klass->GetReferenceStaticOffsets(), true, visitor);
+}
+
+template <typename Visitor>
+inline void MarkSweep::VisitFieldsReferences(const mirror::Object* obj, uint32_t ref_offsets,
+ bool is_static, const Visitor& visitor) {
+ if (LIKELY(ref_offsets != CLASS_WALK_SUPER)) {
+ // Found a reference offset bitmap. Mark the specified offsets.
+ while (ref_offsets != 0) {
+ size_t right_shift = CLZ(ref_offsets);
+ MemberOffset field_offset = CLASS_OFFSET_FROM_CLZ(right_shift);
+ const mirror::Object* ref = obj->GetFieldObject<const mirror::Object*>(field_offset, false);
+ visitor(obj, ref, field_offset, is_static);
+ ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift);
+ }
+ } else {
+ // There is no reference offset bitmap. In the non-static case,
+ // walk up the class inheritance hierarchy and find reference
+ // offsets the hard way. In the static case, just consider this
+ // class.
+ for (const mirror::Class* klass = is_static ? obj->AsClass() : obj->GetClass();
+ klass != NULL;
+ klass = is_static ? NULL : klass->GetSuperClass()) {
+ size_t num_reference_fields = (is_static
+ ? klass->NumReferenceStaticFields()
+ : klass->NumReferenceInstanceFields());
+ for (size_t i = 0; i < num_reference_fields; ++i) {
+ mirror::Field* field = (is_static ? klass->GetStaticField(i)
+ : klass->GetInstanceField(i));
+ MemberOffset field_offset = field->GetOffset();
+ const mirror::Object* ref = obj->GetFieldObject<const mirror::Object*>(field_offset, false);
+ visitor(obj, ref, field_offset, is_static);
+ }
+ }
+ }
+}
+
+template <typename Visitor>
+inline void MarkSweep::VisitObjectArrayReferences(const mirror::ObjectArray<mirror::Object>* array,
+ const Visitor& visitor) {
+ const int32_t length = array->GetLength();
+ for (int32_t i = 0; i < length; ++i) {
+ const mirror::Object* element = array->GetWithoutChecks(i);
+ const size_t width = sizeof(mirror::Object*);
+ MemberOffset offset = MemberOffset(i * width + mirror::Array::DataOffset(width).Int32Value());
+ visitor(array, element, offset, false);
+ }
+}
+
+} // namespace art
+
+#endif // ART_SRC_GC_MARK_SWEEP_INL_H_
diff --git a/src/gc/mark_sweep.cc b/src/gc/mark_sweep.cc
index 7c52c83..40102b2 100644
--- a/src/gc/mark_sweep.cc
+++ b/src/gc/mark_sweep.cc
@@ -25,22 +25,32 @@
#include "base/logging.h"
#include "base/macros.h"
#include "card_table.h"
-#include "class_loader.h"
-#include "dex_cache.h"
+#include "card_table-inl.h"
#include "heap.h"
#include "indirect_reference_table.h"
#include "intern_table.h"
#include "jni_internal.h"
#include "large_object_space.h"
#include "monitor.h"
-#include "object.h"
+#include "mark_sweep-inl.h"
+#include "mirror/class-inl.h"
+#include "mirror/class_loader.h"
+#include "mirror/dex_cache.h"
+#include "mirror/field.h"
+#include "mirror/field-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array.h"
+#include "mirror/object_array-inl.h"
#include "runtime.h"
#include "space.h"
+#include "space_bitmap-inl.h"
#include "timing_logger.h"
#include "thread.h"
#include "thread_list.h"
#include "verifier/method_verifier.h"
+using namespace art::mirror;
+
namespace art {
// Performance options.
@@ -186,7 +196,7 @@
timings_.AddSplit("ReMarkRoots");
// Scan dirty objects, this is only required if we are not doing concurrent GC.
- RecursiveMarkDirtyObjects();
+ RecursiveMarkDirtyObjects(CardTable::kCardDirty);
}
ProcessReferences(self);
@@ -700,7 +710,7 @@
Runtime::Current()->VisitRoots(ReMarkObjectVisitor, this);
}
-void MarkSweep::SweepJniWeakGlobals(Heap::IsMarkedTester is_marked, void* arg) {
+void MarkSweep::SweepJniWeakGlobals(IsMarkedTester is_marked, void* arg) {
JavaVMExt* vm = Runtime::Current()->GetJavaVM();
MutexLock mu(Thread::Current(), vm->weak_globals_lock);
IndirectReferenceTable* table = &vm->weak_globals;
diff --git a/src/gc/mark_sweep.h b/src/gc/mark_sweep.h
index 3581d98..0d43bee 100644
--- a/src/gc/mark_sweep.h
+++ b/src/gc/mark_sweep.h
@@ -14,28 +14,38 @@
* limitations under the License.
*/
-#ifndef ART_SRC_MARK_SWEEP_H_
-#define ART_SRC_MARK_SWEEP_H_
+#ifndef ART_SRC_GC_MARK_SWEEP_H_
+#define ART_SRC_GC_MARK_SWEEP_H_
-#include "atomic_stack.h"
+#include "atomic_integer.h"
#include "base/macros.h"
+#include "base/mutex.h"
#include "garbage_collector.h"
-#include "heap_bitmap.h"
-#include "object.h"
+#include "gc_type.h"
#include "offsets.h"
+#include "root_visitor.h"
+#include "timing_logger.h"
+#include "UniquePtr.h"
namespace art {
-
+namespace mirror {
+class Class;
+class Object;
+template<class T> class ObjectArray;
+}
+template <typename T> class AtomicStack;
class Barrier;
class CheckObjectVisitor;
-class Class;
+class ContinuousSpace;
class Heap;
class MarkIfReachesAllocspaceVisitor;
class ModUnionClearCardVisitor;
class ModUnionVisitor;
class ModUnionTableBitmap;
-class Object;
-class TimingLogger;
+typedef AtomicStack<mirror::Object*> ObjectStack;
+class SpaceBitmap;
+class StackVisitor;
+class Thread;
class MarkStackChunk;
class MarkSweep : public GarbageCollector {
@@ -79,7 +89,9 @@
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
// Verify that image roots point to only marked objects within the alloc space.
- void VerifyImageRoots() EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
+ void VerifyImageRoots()
+ EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Builds a mark stack and recursively mark until it empties.
void RecursiveMark()
@@ -88,8 +100,8 @@
// Make a space immune, immune spaces are assumed to have all live objects marked.
void ImmuneSpace(ContinuousSpace* space)
- EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);;
+ EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Bind the live bits to the mark bits of bitmaps based on the gc type.
virtual void BindBitmaps()
@@ -102,7 +114,7 @@
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
// Builds a mark stack with objects on dirty cards and recursively mark until it empties.
- void RecursiveMarkDirtyObjects(byte minimum_age = CardTable::kCardDirty)
+ void RecursiveMarkDirtyObjects(byte minimum_age)
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -130,61 +142,31 @@
virtual void SwapBitmaps() EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
void SwapLargeObjects() EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
- Object* GetClearedReferences() {
+ mirror::Object* GetClearedReferences() {
return cleared_reference_list_;
}
// Proxy for external access to ScanObject.
- void ScanRoot(const Object* obj)
+ void ScanRoot(const mirror::Object* obj)
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Blackens an object.
- void ScanObject(const Object* obj)
+ void ScanObject(const mirror::Object* obj)
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ // TODO: enable thread safety analysis when in use by multiple worker threads.
template <typename MarkVisitor>
- void ScanObjectVisit(const Object* obj, const MarkVisitor& visitor)
- NO_THREAD_SAFETY_ANALYSIS {
- DCHECK(obj != NULL);
- if (kIsDebugBuild && !IsMarked(obj)) {
- heap_->DumpSpaces();
- LOG(FATAL) << "Scanning unmarked object " << obj;
- }
- Class* klass = obj->GetClass();
- DCHECK(klass != NULL);
- if (klass == java_lang_Class_) {
- DCHECK_EQ(klass->GetClass(), java_lang_Class_);
- if (kCountScannedTypes) {
- ++class_count_;
- }
- VisitClassReferences(klass, obj, visitor);
- } else if (klass->IsArrayClass()) {
- if (kCountScannedTypes) {
- ++array_count_;
- }
- visitor(obj, klass, Object::ClassOffset(), false);
- if (klass->IsObjectArrayClass()) {
- VisitObjectArrayReferences(obj->AsObjectArray<Object>(), visitor);
- }
- } else {
- if (kCountScannedTypes) {
- ++other_count_;
- }
- VisitOtherReferences(klass, obj, visitor);
- if (UNLIKELY(klass->IsReferenceClass())) {
- DelayReferenceReferent(const_cast<Object*>(obj));
- }
- }
- }
+ void ScanObjectVisit(const mirror::Object* obj, const MarkVisitor& visitor)
+ NO_THREAD_SAFETY_ANALYSIS;
- void SetFinger(Object* new_finger) {
+ void SetFinger(mirror::Object* new_finger) {
finger_ = new_finger;
}
void DisableFinger() {
- SetFinger(reinterpret_cast<Object*>(~static_cast<uintptr_t>(0)));
+ SetFinger(reinterpret_cast<mirror::Object*>(~static_cast<uintptr_t>(0)));
}
size_t GetFreedBytes() const {
@@ -212,7 +194,7 @@
}
// Everything inside the immune range is assumed to be marked.
- void SetImmuneRange(Object* begin, Object* end);
+ void SetImmuneRange(mirror::Object* begin, mirror::Object* end);
void SweepSystemWeaks()
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
@@ -221,52 +203,33 @@
void SweepSystemWeaksArray(ObjectStack* allocations)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
- static bool VerifyIsLiveCallback(const Object* obj, void* arg)
+ static bool VerifyIsLiveCallback(const mirror::Object* obj, void* arg)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
void VerifySystemWeaks()
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
// Verify that an object is live, either in a live bitmap or in the allocation stack.
- void VerifyIsLive(const Object* obj)
+ void VerifyIsLive(const mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
template <typename Visitor>
- static void VisitObjectReferences(const Object* obj, const Visitor& visitor)
+ static void VisitObjectReferences(const mirror::Object* obj, const Visitor& visitor)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_,
- Locks::mutator_lock_) {
- DCHECK(obj != NULL);
- DCHECK(obj->GetClass() != NULL);
+ Locks::mutator_lock_);
- Class* klass = obj->GetClass();
- DCHECK(klass != NULL);
- if (klass == Class::GetJavaLangClass()) {
- DCHECK_EQ(klass->GetClass(), Class::GetJavaLangClass());
- VisitClassReferences(klass, obj, visitor);
- } else {
- if (klass->IsArrayClass()) {
- visitor(obj, klass, Object::ClassOffset(), false);
- if (klass->IsObjectArrayClass()) {
- VisitObjectArrayReferences(obj->AsObjectArray<Object>(), visitor);
- }
- } else {
- VisitOtherReferences(klass, obj, visitor);
- }
- }
- }
-
- static void MarkObjectCallback(const Object* root, void* arg)
+ static void MarkObjectCallback(const mirror::Object* root, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
- static void MarkRootParallelCallback(const Object* root, void* arg);
+ static void MarkRootParallelCallback(const mirror::Object* root, void* arg);
// Marks an object.
- void MarkObject(const Object* obj)
+ void MarkObject(const mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
- void MarkRoot(const Object* obj)
+ void MarkRoot(const mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
@@ -277,45 +240,46 @@
protected:
// Returns true if the object has its bit set in the mark bitmap.
- bool IsMarked(const Object* object) const;
+ bool IsMarked(const mirror::Object* object) const;
- static bool IsMarkedCallback(const Object* object, void* arg)
+ static bool IsMarkedCallback(const mirror::Object* object, void* arg)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
- static bool IsMarkedArrayCallback(const Object* object, void* arg)
+ static bool IsMarkedArrayCallback(const mirror::Object* object, void* arg)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
- static void ReMarkObjectVisitor(const Object* root, void* arg)
+ static void ReMarkObjectVisitor(const mirror::Object* root, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
- static void VerifyImageRootVisitor(Object* root, void* arg)
+ static void VerifyImageRootVisitor(mirror::Object* root, void* arg)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_,
Locks::mutator_lock_);
- void MarkObjectNonNull(const Object* obj, bool check_finger)
+ void MarkObjectNonNull(const mirror::Object* obj, bool check_finger)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
- void MarkObjectNonNullParallel(const Object* obj, bool check_finger);
+ void MarkObjectNonNullParallel(const mirror::Object* obj, bool check_finger);
- bool MarkLargeObject(const Object* obj)
+ bool MarkLargeObject(const mirror::Object* obj)
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
// Returns true if we need to add obj to a mark stack.
- bool MarkObjectParallel(const Object* obj) NO_THREAD_SAFETY_ANALYSIS;
+ bool MarkObjectParallel(const mirror::Object* obj) NO_THREAD_SAFETY_ANALYSIS;
- static void SweepCallback(size_t num_ptrs, Object** ptrs, void* arg)
+ static void SweepCallback(size_t num_ptrs, mirror::Object** ptrs, void* arg)
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
// Special sweep for zygote that just marks objects / dirties cards.
- static void ZygoteSweepCallback(size_t num_ptrs, Object** ptrs, void* arg)
+ static void ZygoteSweepCallback(size_t num_ptrs, mirror::Object** ptrs, void* arg)
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
- void CheckReference(const Object* obj, const Object* ref, MemberOffset offset, bool is_static)
+ void CheckReference(const mirror::Object* obj, const mirror::Object* ref, MemberOffset offset,
+ bool is_static)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
- void CheckObject(const Object* obj)
+ void CheckObject(const mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
// Verify the roots of the heap and print out information related to any invalid roots.
@@ -326,90 +290,41 @@
// Expand mark stack to 2x its current size. Thread safe.
void ExpandMarkStack();
- static void VerifyRootCallback(const Object* root, void* arg, size_t vreg,
+ static void VerifyRootCallback(const mirror::Object* root, void* arg, size_t vreg,
const StackVisitor *visitor);
- void VerifyRoot(const Object* root, size_t vreg, const StackVisitor* visitor)
+ void VerifyRoot(const mirror::Object* root, size_t vreg, const StackVisitor* visitor)
NO_THREAD_SAFETY_ANALYSIS;
template <typename Visitor>
- static void VisitInstanceFieldsReferences(const Class* klass, const Object* obj,
+ static void VisitInstanceFieldsReferences(const mirror::Class* klass, const mirror::Object* obj,
const Visitor& visitor)
- SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
- DCHECK(obj != NULL);
- DCHECK(klass != NULL);
- VisitFieldsReferences(obj, klass->GetReferenceInstanceOffsets(), false, visitor);
- }
+ SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
// Visit the header, static field references, and interface pointers of a class object.
template <typename Visitor>
- static void VisitClassReferences(const Class* klass, const Object* obj,
+ static void VisitClassReferences(const mirror::Class* klass, const mirror::Object* obj,
const Visitor& visitor)
- SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
- VisitInstanceFieldsReferences(klass, obj, visitor);
- VisitStaticFieldsReferences(obj->AsClass(), visitor);
- }
+ SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
template <typename Visitor>
- static void VisitStaticFieldsReferences(const Class* klass, const Visitor& visitor)
- SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
- DCHECK(klass != NULL);
- VisitFieldsReferences(klass, klass->GetReferenceStaticOffsets(), true, visitor);
- }
+ static void VisitStaticFieldsReferences(const mirror::Class* klass, const Visitor& visitor)
+ SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
template <typename Visitor>
- static void VisitFieldsReferences(const Object* obj, uint32_t ref_offsets, bool is_static,
- const Visitor& visitor)
- SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
- if (LIKELY(ref_offsets != CLASS_WALK_SUPER)) {
- // Found a reference offset bitmap. Mark the specified offsets.
- while (ref_offsets != 0) {
- size_t right_shift = CLZ(ref_offsets);
- MemberOffset field_offset = CLASS_OFFSET_FROM_CLZ(right_shift);
- const Object* ref = obj->GetFieldObject<const Object*>(field_offset, false);
- visitor(obj, ref, field_offset, is_static);
- ref_offsets &= ~(CLASS_HIGH_BIT >> right_shift);
- }
- } else {
- // There is no reference offset bitmap. In the non-static case,
- // walk up the class inheritance hierarchy and find reference
- // offsets the hard way. In the static case, just consider this
- // class.
- for (const Class* klass = is_static ? obj->AsClass() : obj->GetClass();
- klass != NULL;
- klass = is_static ? NULL : klass->GetSuperClass()) {
- size_t num_reference_fields = (is_static
- ? klass->NumReferenceStaticFields()
- : klass->NumReferenceInstanceFields());
- for (size_t i = 0; i < num_reference_fields; ++i) {
- Field* field = (is_static
- ? klass->GetStaticField(i)
- : klass->GetInstanceField(i));
- MemberOffset field_offset = field->GetOffset();
- const Object* ref = obj->GetFieldObject<const Object*>(field_offset, false);
- visitor(obj, ref, field_offset, is_static);
- }
- }
- }
- }
+ static void VisitFieldsReferences(const mirror::Object* obj, uint32_t ref_offsets, bool is_static,
+ const Visitor& visitor)
+ SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
// Visit all of the references in an object array.
template <typename Visitor>
- static void VisitObjectArrayReferences(const ObjectArray<Object>* array,
+ static void VisitObjectArrayReferences(const mirror::ObjectArray<mirror::Object>* array,
const Visitor& visitor)
- SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
- const int32_t length = array->GetLength();
- for (int32_t i = 0; i < length; ++i) {
- const Object* element = array->GetWithoutChecks(i);
- const size_t width = sizeof(Object*);
- MemberOffset offset = MemberOffset(i * width + Array::DataOffset(width).Int32Value());
- visitor(array, element, offset, false);
- }
- }
+ SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
// Visits the header and field references of a data object.
template <typename Visitor>
- static void VisitOtherReferences(const Class* klass, const Object* obj,
+ static void VisitOtherReferences(const mirror::Class* klass, const mirror::Object* obj,
const Visitor& visitor)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
return VisitInstanceFieldsReferences(klass, obj, visitor);
@@ -421,7 +336,7 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Schedules an unmarked object for reference processing.
- void DelayReferenceReferent(Object* reference)
+ void DelayReferenceReferent(mirror::Object* reference)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
// Recursively blackens objects on the mark stack.
@@ -433,25 +348,25 @@
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void EnqueueFinalizerReferences(Object** ref)
+ void EnqueueFinalizerReferences(mirror::Object** ref)
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void PreserveSomeSoftReferences(Object** ref)
+ void PreserveSomeSoftReferences(mirror::Object** ref)
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void ClearWhiteReferences(Object** list)
+ void ClearWhiteReferences(mirror::Object** list)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
- void ProcessReferences(Object** soft_references, bool clear_soft_references,
- Object** weak_references,
- Object** finalizer_references,
- Object** phantom_references)
+ void ProcessReferences(mirror::Object** soft_references, bool clear_soft_references,
+ mirror::Object** weak_references,
+ mirror::Object** finalizer_references,
+ mirror::Object** phantom_references)
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SweepJniWeakGlobals(Heap::IsMarkedTester is_marked, void* arg)
+ void SweepJniWeakGlobals(IsMarkedTester is_marked, void* arg)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
// Whether or not we count how many of each type of object were scanned.
@@ -461,21 +376,21 @@
SpaceBitmap* current_mark_bitmap_;
// Cache java.lang.Class for optimization.
- Class* java_lang_Class_;
+ mirror::Class* java_lang_Class_;
ObjectStack* mark_stack_;
- Object* finger_;
+ mirror::Object* finger_;
// Immune range, every object inside the immune range is assumed to be marked.
- Object* immune_begin_;
- Object* immune_end_;
+ mirror::Object* immune_begin_;
+ mirror::Object* immune_end_;
- Object* soft_reference_list_;
- Object* weak_reference_list_;
- Object* finalizer_reference_list_;
- Object* phantom_reference_list_;
- Object* cleared_reference_list_;
+ mirror::Object* soft_reference_list_;
+ mirror::Object* weak_reference_list_;
+ mirror::Object* finalizer_reference_list_;
+ mirror::Object* phantom_reference_list_;
+ mirror::Object* cleared_reference_list_;
AtomicInteger freed_bytes_;
AtomicInteger freed_objects_;
@@ -529,4 +444,4 @@
} // namespace art
-#endif // ART_SRC_MARK_SWEEP_H_
+#endif // ART_SRC_GC_MARK_SWEEP_H_
diff --git a/src/gc/mod_union_table-inl.h b/src/gc/mod_union_table-inl.h
new file mode 100644
index 0000000..c1c69fb
--- /dev/null
+++ b/src/gc/mod_union_table-inl.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_GC_MOD_UNION_TABLE_INL_H_
+#define ART_SRC_GC_MOD_UNION_TABLE_INL_H_
+
+#include "mod_union_table.h"
+
+namespace art {
+
+template <typename Implementation>
+class ModUnionTableToZygoteAllocspace : public Implementation {
+public:
+ ModUnionTableToZygoteAllocspace(Heap* heap) : Implementation(heap) {
+ }
+
+ bool AddReference(const mirror::Object* /* obj */, const mirror::Object* ref) {
+ const Spaces& spaces = Implementation::GetHeap()->GetSpaces();
+ for (Spaces::const_iterator it = spaces.begin(); it != spaces.end(); ++it) {
+ if ((*it)->Contains(ref)) {
+ return (*it)->IsAllocSpace();
+ }
+ }
+ // Assume it points to a large object.
+ // TODO: Check.
+ return true;
+ }
+};
+
+template <typename Implementation>
+class ModUnionTableToAllocspace : public Implementation {
+public:
+ ModUnionTableToAllocspace(Heap* heap) : Implementation(heap) {
+ }
+
+ bool AddReference(const mirror::Object* /* obj */, const mirror::Object* ref) {
+ const Spaces& spaces = Implementation::GetHeap()->GetSpaces();
+ for (Spaces::const_iterator it = spaces.begin(); it != spaces.end(); ++it) {
+ if ((*it)->Contains(ref)) {
+ return (*it)->GetGcRetentionPolicy() == kGcRetentionPolicyAlwaysCollect;
+ }
+ }
+ // Assume it points to a large object.
+ // TODO: Check.
+ return true;
+ }
+};
+
+} // namespace art
+
+#endif // ART_SRC_GC_MOD_UNION_TABLE_INL_H_
diff --git a/src/gc/mod_union_table.cc b/src/gc/mod_union_table.cc
index 8953c5a..da950bb 100644
--- a/src/gc/mod_union_table.cc
+++ b/src/gc/mod_union_table.cc
@@ -17,12 +17,22 @@
#include "mod_union_table.h"
#include "base/stl_util.h"
+#include "card_table-inl.h"
#include "heap.h"
#include "heap_bitmap.h"
#include "mark_sweep.h"
+#include "mark_sweep-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/class-inl.h"
+#include "mirror/field-inl.h"
+#include "mirror/object_array-inl.h"
#include "space.h"
+#include "space_bitmap-inl.h"
+#include "thread.h"
#include "UniquePtr.h"
+using namespace art::mirror;
+
namespace art {
class MarkIfReachesAllocspaceVisitor {
@@ -260,7 +270,7 @@
// TODO: Fixme when anotatalysis works with visitors.
void operator ()(const Object* obj, const Object* ref, const MemberOffset& /* offset */,
bool /* is_static */) const
- SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
+ SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_) {
Heap* heap = mod_union_table_->GetHeap();
if (ref != NULL && mod_union_table_->AddReference(obj, ref) &&
references_.find(ref) == references_.end()) {
diff --git a/src/gc/mod_union_table.h b/src/gc/mod_union_table.h
index f3da41c..23c0a51 100644
--- a/src/gc/mod_union_table.h
+++ b/src/gc/mod_union_table.h
@@ -14,23 +14,30 @@
* limitations under the License.
*/
-#ifndef ART_SRC_MOD_UNION_TABLE_H_
-#define ART_SRC_MOD_UNION_TABLE_H_
+#ifndef ART_SRC_GC_MOD_UNION_TABLE_H_
+#define ART_SRC_GC_MOD_UNION_TABLE_H_
-#include "heap.h"
+#include "globals.h"
#include "safe_map.h"
-#include "space.h"
+
+#include <set>
+#include <vector>
namespace art {
-
+namespace mirror {
+class Object;
+}
+class ContinuousSpace;
class Heap;
class HeapBitmap;
+class MarkSweep;
class Space;
+class SpaceBitmap;
// Base class
class ModUnionTable {
public:
- typedef std::vector<const Object*> ReferenceArray;
+ typedef std::vector<const mirror::Object*> ReferenceArray;
typedef std::set<byte*> ClearedCards;
ModUnionTable(Heap* heap) : heap_(heap) {
@@ -118,7 +125,7 @@
void Verify() EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
// Function that tells whether or not to add a reference to the table.
- virtual bool AddReference(const Object* obj, const Object* ref) = 0;
+ virtual bool AddReference(const mirror::Object* obj, const mirror::Object* ref) = 0;
protected:
// Cleared card array, used to update the mod-union table.
@@ -155,44 +162,6 @@
ClearedCards cleared_cards_;
};
-template <typename Implementation>
-class ModUnionTableToZygoteAllocspace : public Implementation {
-public:
- ModUnionTableToZygoteAllocspace(Heap* heap) : Implementation(heap) {
- }
-
- bool AddReference(const Object* /* obj */, const Object* ref) {
- const Spaces& spaces = Implementation::GetHeap()->GetSpaces();
- for (Spaces::const_iterator it = spaces.begin(); it != spaces.end(); ++it) {
- if ((*it)->Contains(ref)) {
- return (*it)->IsAllocSpace();
- }
- }
- // Assume it points to a large object.
- // TODO: Check.
- return true;
- }
-};
-
-template <typename Implementation>
-class ModUnionTableToAllocspace : public Implementation {
-public:
- ModUnionTableToAllocspace(Heap* heap) : Implementation(heap) {
- }
-
- bool AddReference(const Object* /* obj */, const Object* ref) {
- const Spaces& spaces = Implementation::GetHeap()->GetSpaces();
- for (Spaces::const_iterator it = spaces.begin(); it != spaces.end(); ++it) {
- if ((*it)->Contains(ref)) {
- return (*it)->GetGcRetentionPolicy() == kGcRetentionPolicyAlwaysCollect;
- }
- }
- // Assume it points to a large object.
- // TODO: Check.
- return true;
- }
-};
-
} // namespace art
-#endif // ART_SRC_MOD_UNION_TABLE_H_
+#endif // ART_SRC_GC_MOD_UNION_TABLE_H_
diff --git a/src/gc/partial_mark_sweep.cc b/src/gc/partial_mark_sweep.cc
index 64f09ff..f9c1787 100644
--- a/src/gc/partial_mark_sweep.cc
+++ b/src/gc/partial_mark_sweep.cc
@@ -14,32 +14,38 @@
* limitations under the License.
*/
+#include "partial_mark_sweep.h"
+
+#include "heap.h"
#include "large_object_space.h"
#include "partial_mark_sweep.h"
#include "space.h"
+#include "thread.h"
namespace art {
- PartialMarkSweep::PartialMarkSweep(Heap* heap, bool is_concurrent)
- : MarkSweep(heap, is_concurrent) {
- cumulative_timings_.SetName(GetName());
- }
- PartialMarkSweep::~PartialMarkSweep() {
+PartialMarkSweep::PartialMarkSweep(Heap* heap, bool is_concurrent)
+ : MarkSweep(heap, is_concurrent) {
+ cumulative_timings_.SetName(GetName());
+}
- }
+PartialMarkSweep::~PartialMarkSweep() {
- void PartialMarkSweep::BindBitmaps() {
- MarkSweep::BindBitmaps();
+}
- Spaces& spaces = GetHeap()->GetSpaces();
- WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
- // For partial GCs we need to bind the bitmap of the zygote space so that all objects in the
- // zygote space are viewed as marked.
- for (Spaces::iterator it = spaces.begin(); it != spaces.end(); ++it) {
- ContinuousSpace* space = *it;
- if (space->GetGcRetentionPolicy() == kGcRetentionPolicyFullCollect) {
- ImmuneSpace(space);
- }
+void PartialMarkSweep::BindBitmaps() {
+ MarkSweep::BindBitmaps();
+
+ Spaces& spaces = GetHeap()->GetSpaces();
+ WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
+ // For partial GCs we need to bind the bitmap of the zygote space so that all objects in the
+ // zygote space are viewed as marked.
+ for (Spaces::iterator it = spaces.begin(); it != spaces.end(); ++it) {
+ ContinuousSpace* space = *it;
+ if (space->GetGcRetentionPolicy() == kGcRetentionPolicyFullCollect) {
+ ImmuneSpace(space);
}
}
+}
+
} // namespace art
diff --git a/src/gc/partial_mark_sweep.h b/src/gc/partial_mark_sweep.h
index 80a1563..64c0bcd 100644
--- a/src/gc/partial_mark_sweep.h
+++ b/src/gc/partial_mark_sweep.h
@@ -14,27 +14,14 @@
* limitations under the License.
*/
-#ifndef ART_SRC_PARTIAL_MARK_SWEEP_H_
-#define ART_SRC_PARTIAL_MARK_SWEEP_H_
+#ifndef ART_SRC_GC_PARTIAL_MARK_SWEEP_H_
+#define ART_SRC_GC_PARTIAL_MARK_SWEEP_H_
#include "locks.h"
#include "mark_sweep.h"
-#include "utils.h"
namespace art {
-class Barrier;
-class CheckObjectVisitor;
-class Class;
-class Heap;
-class MarkIfReachesAllocspaceVisitor;
-class ModUnionClearCardVisitor;
-class ModUnionVisitor;
-class ModUnionTableBitmap;
-class Object;
-class TimingLogger;
-class MarkStackChunk;
-
class PartialMarkSweep : public MarkSweep {
public:
virtual GcType GetGcType() const {
@@ -53,4 +40,4 @@
} // namespace art
-#endif // ART_SRC_PARTIAL_MARK_SWEEP_H_
+#endif // ART_SRC_GC_PARTIAL_MARK_SWEEP_H_
diff --git a/src/gc/space.cc b/src/gc/space.cc
index 04f932d..9db84f2 100644
--- a/src/gc/space.cc
+++ b/src/gc/space.cc
@@ -19,10 +19,16 @@
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/unix_file/fd_file.h"
+#include "card_table.h"
#include "dlmalloc.h"
#include "image.h"
+#include "mirror/array.h"
+#include "mirror/abstract_method.h"
#include "os.h"
+#include "runtime.h"
#include "space_bitmap.h"
+#include "space_bitmap-inl.h"
+#include "thread.h"
#include "UniquePtr.h"
#include "utils.h"
@@ -204,12 +210,12 @@
mark_bitmap_->SetName(temp_name);
}
-Object* DlMallocSpace::AllocWithoutGrowthLocked(size_t num_bytes) {
+mirror::Object* DlMallocSpace::AllocWithoutGrowthLocked(size_t num_bytes) {
if (kDebugSpaces) {
num_bytes += sizeof(word);
}
- Object* result = reinterpret_cast<Object*>(mspace_calloc(mspace_, 1, num_bytes));
+ mirror::Object* result = reinterpret_cast<mirror::Object*>(mspace_calloc(mspace_, 1, num_bytes));
if (kDebugSpaces && result != NULL) {
CHECK(Contains(result)) << "Allocation (" << reinterpret_cast<void*>(result)
<< ") not in bounds of allocation space " << *this;
@@ -225,18 +231,18 @@
return result;
}
-Object* DlMallocSpace::Alloc(Thread* self, size_t num_bytes) {
+mirror::Object* DlMallocSpace::Alloc(Thread* self, size_t num_bytes) {
MutexLock mu(self, lock_);
return AllocWithoutGrowthLocked(num_bytes);
}
-Object* DlMallocSpace::AllocWithGrowth(Thread* self, size_t num_bytes) {
+mirror::Object* DlMallocSpace::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);
// Try the allocation.
- Object* result = AllocWithoutGrowthLocked(num_bytes);
+ mirror::Object* result = AllocWithoutGrowthLocked(num_bytes);
// Shrink back down as small as possible.
size_t footprint = mspace_footprint(mspace_);
mspace_set_footprint_limit(mspace_, footprint);
@@ -301,7 +307,7 @@
return alloc_space;
}
-size_t DlMallocSpace::Free(Thread* self, Object* ptr) {
+size_t DlMallocSpace::Free(Thread* self, mirror::Object* ptr) {
MutexLock mu(self, lock_);
if (kDebugSpaces) {
CHECK(ptr != NULL);
@@ -317,13 +323,13 @@
return bytes_freed;
}
-size_t DlMallocSpace::FreeList(Thread* self, size_t num_ptrs, Object** ptrs) {
+size_t DlMallocSpace::FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) {
DCHECK(ptrs != NULL);
// Don't need the lock to calculate the size of the freed pointers.
size_t bytes_freed = 0;
for (size_t i = 0; i < num_ptrs; i++) {
- Object* ptr = ptrs[i];
+ mirror::Object* ptr = ptrs[i];
const size_t look_ahead = 8;
if (kPrefetchDuringDlMallocFreeList && i + look_ahead < num_ptrs) {
// The head of chunk for the allocation is sizeof(size_t) behind the allocation.
@@ -397,12 +403,12 @@
}
// Virtual functions can't get inlined.
-inline size_t DlMallocSpace::InternalAllocationSize(const Object* obj) {
+inline size_t DlMallocSpace::InternalAllocationSize(const mirror::Object* obj) {
return mspace_usable_size(const_cast<void*>(reinterpret_cast<const void*>(obj))) +
kChunkOverhead;
}
-size_t DlMallocSpace::AllocationSize(const Object* obj) {
+size_t DlMallocSpace::AllocationSize(const mirror::Object* obj) {
return InternalAllocationSize(obj);
}
@@ -504,29 +510,29 @@
DCHECK_EQ(0, memcmp(&image_header, map->Begin(), sizeof(ImageHeader)));
Runtime* runtime = Runtime::Current();
- Object* jni_stub_array = image_header.GetImageRoot(ImageHeader::kJniStubArray);
- runtime->SetJniDlsymLookupStub(down_cast<ByteArray*>(jni_stub_array));
+ mirror::Object* jni_stub_array = image_header.GetImageRoot(ImageHeader::kJniStubArray);
+ runtime->SetJniDlsymLookupStub(down_cast<mirror::ByteArray*>(jni_stub_array));
- Object* ame_stub_array = image_header.GetImageRoot(ImageHeader::kAbstractMethodErrorStubArray);
- runtime->SetAbstractMethodErrorStubArray(down_cast<ByteArray*>(ame_stub_array));
+ mirror::Object* ame_stub_array = image_header.GetImageRoot(ImageHeader::kAbstractMethodErrorStubArray);
+ runtime->SetAbstractMethodErrorStubArray(down_cast<mirror::ByteArray*>(ame_stub_array));
- Object* resolution_stub_array =
+ mirror::Object* resolution_stub_array =
image_header.GetImageRoot(ImageHeader::kStaticResolutionStubArray);
runtime->SetResolutionStubArray(
- down_cast<ByteArray*>(resolution_stub_array), Runtime::kStaticMethod);
+ down_cast<mirror::ByteArray*>(resolution_stub_array), Runtime::kStaticMethod);
resolution_stub_array = image_header.GetImageRoot(ImageHeader::kUnknownMethodResolutionStubArray);
runtime->SetResolutionStubArray(
- down_cast<ByteArray*>(resolution_stub_array), Runtime::kUnknownMethod);
+ down_cast<mirror::ByteArray*>(resolution_stub_array), Runtime::kUnknownMethod);
- Object* resolution_method = image_header.GetImageRoot(ImageHeader::kResolutionMethod);
- runtime->SetResolutionMethod(down_cast<AbstractMethod*>(resolution_method));
+ mirror::Object* resolution_method = image_header.GetImageRoot(ImageHeader::kResolutionMethod);
+ runtime->SetResolutionMethod(down_cast<mirror::AbstractMethod*>(resolution_method));
- Object* callee_save_method = image_header.GetImageRoot(ImageHeader::kCalleeSaveMethod);
- runtime->SetCalleeSaveMethod(down_cast<AbstractMethod*>(callee_save_method), Runtime::kSaveAll);
+ mirror::Object* callee_save_method = image_header.GetImageRoot(ImageHeader::kCalleeSaveMethod);
+ runtime->SetCalleeSaveMethod(down_cast<mirror::AbstractMethod*>(callee_save_method), Runtime::kSaveAll);
callee_save_method = image_header.GetImageRoot(ImageHeader::kRefsOnlySaveMethod);
- runtime->SetCalleeSaveMethod(down_cast<AbstractMethod*>(callee_save_method), Runtime::kRefsOnly);
+ runtime->SetCalleeSaveMethod(down_cast<mirror::AbstractMethod*>(callee_save_method), Runtime::kRefsOnly);
callee_save_method = image_header.GetImageRoot(ImageHeader::kRefsAndArgsSaveMethod);
- runtime->SetCalleeSaveMethod(down_cast<AbstractMethod*>(callee_save_method), Runtime::kRefsAndArgs);
+ runtime->SetCalleeSaveMethod(down_cast<mirror::AbstractMethod*>(callee_save_method), Runtime::kRefsAndArgs);
ImageSpace* space = new ImageSpace(image_file_name, map.release());
if (VLOG_IS_ON(heap) || VLOG_IS_ON(startup)) {
@@ -548,7 +554,7 @@
byte* end = End();
while (current < end) {
DCHECK_ALIGNED(current, kObjectAlignment);
- const Object* obj = reinterpret_cast<const Object*>(current);
+ const mirror::Object* obj = reinterpret_cast<const mirror::Object*>(current);
live_bitmap->Set(obj);
current += RoundUp(obj->SizeOf(), kObjectAlignment);
}
diff --git a/src/gc/space.h b/src/gc/space.h
index 2ed4988..d2bcd53 100644
--- a/src/gc/space.h
+++ b/src/gc/space.h
@@ -31,10 +31,12 @@
static const bool kDebugSpaces = kIsDebugBuild;
+namespace mirror {
+class Object;
+} // namespace mirror
class DlMallocSpace;
class ImageSpace;
class LargeObjectSpace;
-class Object;
class SpaceBitmap;
enum GcRetentionPolicy {
@@ -57,7 +59,7 @@
public:
virtual bool CanAllocateInto() const = 0;
virtual bool IsCompactible() const = 0;
- virtual bool Contains(const Object* obj) const = 0;
+ virtual bool Contains(const mirror::Object* obj) const = 0;
virtual SpaceType GetType() const = 0;
virtual GcRetentionPolicy GetGcRetentionPolicy() const = 0;
virtual std::string GetName() const = 0;
@@ -108,16 +110,16 @@
virtual uint64_t GetTotalObjectsAllocated() const = 0;
// Allocate num_bytes without allowing growth.
- virtual Object* Alloc(Thread* self, size_t num_bytes) = 0;
+ virtual mirror::Object* Alloc(Thread* self, size_t num_bytes) = 0;
// Return the storage space required by obj.
- virtual size_t AllocationSize(const Object* obj) = 0;
+ virtual size_t AllocationSize(const mirror::Object* obj) = 0;
// Returns how many bytes were freed.
- virtual size_t Free(Thread* self, Object* ptr) = 0;
+ virtual size_t Free(Thread* self, mirror::Object* ptr) = 0;
// Returns how many bytes were freed.
- virtual size_t FreeList(Thread* self, size_t num_ptrs, Object** ptrs) = 0;
+ virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) = 0;
protected:
AllocSpace() {}
@@ -149,12 +151,12 @@
virtual SpaceBitmap* GetMarkBitmap() const = 0;
// Is object within this space?
- bool HasAddress(const Object* obj) const {
+ bool HasAddress(const mirror::Object* obj) const {
const byte* byte_ptr = reinterpret_cast<const byte*>(obj);
return Begin() <= byte_ptr && byte_ptr < End();
}
- virtual bool Contains(const Object* obj) const {
+ virtual bool Contains(const mirror::Object* obj) const {
return HasAddress(obj);
}
@@ -188,7 +190,7 @@
class DiscontinuousSpace : public virtual Space {
public:
// Is object within this space?
- virtual bool Contains(const Object* obj) const = 0;
+ virtual bool Contains(const mirror::Object* obj) const = 0;
virtual std::string GetName() const {
return name_;
@@ -267,15 +269,15 @@
size_t capacity, byte* requested_begin);
// Allocate num_bytes without allowing the underlying mspace to grow.
- virtual Object* AllocWithGrowth(Thread* self, size_t num_bytes);
+ virtual mirror::Object* AllocWithGrowth(Thread* self, size_t num_bytes);
// Allocate num_bytes allowing the underlying mspace to grow.
- virtual Object* Alloc(Thread* self, size_t num_bytes);
+ virtual mirror::Object* Alloc(Thread* self, size_t num_bytes);
// Return the storage space required by obj.
- virtual size_t AllocationSize(const Object* obj);
- virtual size_t Free(Thread* self, Object* ptr);
- virtual size_t FreeList(Thread* self, size_t num_ptrs, Object** ptrs);
+ virtual size_t AllocationSize(const mirror::Object* obj);
+ virtual size_t Free(Thread* self, mirror::Object* ptr);
+ virtual size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs);
void* MoreCore(intptr_t increment);
@@ -353,8 +355,8 @@
}
private:
- size_t InternalAllocationSize(const Object* obj);
- Object* AllocWithoutGrowthLocked(size_t num_bytes) EXCLUSIVE_LOCKS_REQUIRED(lock_);
+ size_t InternalAllocationSize(const mirror::Object* obj);
+ mirror::Object* AllocWithoutGrowthLocked(size_t num_bytes) EXCLUSIVE_LOCKS_REQUIRED(lock_);
UniquePtr<SpaceBitmap> live_bitmap_;
UniquePtr<SpaceBitmap> mark_bitmap_;
diff --git a/src/gc/space_bitmap-inl.h b/src/gc/space_bitmap-inl.h
new file mode 100644
index 0000000..e1fdd29
--- /dev/null
+++ b/src/gc/space_bitmap-inl.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_GC_SPACE_BITMAP_INL_H_
+#define ART_SRC_GC_SPACE_BITMAP_INL_H_
+
+#include "base/logging.h"
+#include "cutils/atomic.h"
+
+namespace art {
+
+inline bool SpaceBitmap::AtomicTestAndSet(const mirror::Object* obj) {
+ uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
+ DCHECK_GE(addr, heap_begin_);
+ const uintptr_t offset = addr - heap_begin_;
+ const size_t index = OffsetToIndex(offset);
+ const word mask = OffsetToMask(offset);
+ word* const address = &bitmap_begin_[index];
+ DCHECK_LT(index, bitmap_size_ / kWordSize) << " bitmap_size_ = " << bitmap_size_;
+ word old_word;
+ do {
+ old_word = *address;
+ // Fast path: The bit is already set.
+ if ((old_word & mask) != 0) {
+ return true;
+ }
+ } while (UNLIKELY(android_atomic_cas(old_word, old_word | mask, address) != 0));
+ return false;
+}
+
+inline bool SpaceBitmap::Test(const mirror::Object* obj) const {
+ uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
+ DCHECK(HasAddress(obj)) << obj;
+ DCHECK(bitmap_begin_ != NULL);
+ DCHECK_GE(addr, heap_begin_);
+ const uintptr_t offset = addr - heap_begin_;
+ return (bitmap_begin_[OffsetToIndex(offset)] & OffsetToMask(offset)) != 0;
+}
+
+template <typename Visitor, typename FingerVisitor>
+void SpaceBitmap::VisitMarkedRange(uintptr_t visit_begin, uintptr_t visit_end,
+ const Visitor& visitor,
+ const FingerVisitor& finger_visitor) const {
+ DCHECK_LT(visit_begin, visit_end);
+
+ const size_t word_span = kAlignment * kBitsPerWord; // Equals IndexToOffset(1).
+ const size_t bit_index_start = (visit_begin - heap_begin_) / kAlignment;
+ const size_t bit_index_end = (visit_end - heap_begin_ - 1) / kAlignment;
+
+ size_t word_start = bit_index_start / kBitsPerWord;
+ size_t word_end = bit_index_end / kBitsPerWord;
+ DCHECK_LT(word_end * kWordSize, Size());
+
+ // Trim off left_bits of left bits.
+ size_t edge_word = bitmap_begin_[word_start];
+
+ // Handle bits on the left first as a special case
+ size_t left_bits = bit_index_start & (kBitsPerWord - 1);
+ if (left_bits != 0) {
+ edge_word &= (1 << (kBitsPerWord - left_bits)) - 1;
+ }
+
+ // If word_start == word_end then handle this case at the same place we handle the right edge.
+ if (edge_word != 0 && word_start < word_end) {
+ uintptr_t ptr_base = IndexToOffset(word_start) + heap_begin_;
+ finger_visitor(reinterpret_cast<void*>(ptr_base + word_span));
+ do {
+ const size_t shift = CLZ(edge_word);
+ mirror::Object* obj = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
+ visitor(obj);
+ edge_word ^= static_cast<size_t>(kWordHighBitMask) >> shift;
+ } while (edge_word != 0);
+ }
+ word_start++;
+
+ for (size_t i = word_start; i < word_end; i++) {
+ size_t w = bitmap_begin_[i];
+ if (w != 0) {
+ uintptr_t ptr_base = IndexToOffset(i) + heap_begin_;
+ finger_visitor(reinterpret_cast<void*>(ptr_base + word_span));
+ do {
+ const size_t shift = CLZ(w);
+ mirror::Object* obj = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
+ visitor(obj);
+ w ^= static_cast<size_t>(kWordHighBitMask) >> shift;
+ } while (w != 0);
+ }
+ }
+
+ // Handle the right edge, and also the left edge if both edges are on the same word.
+ size_t right_bits = bit_index_end & (kBitsPerWord - 1);
+
+ // If word_start == word_end then we need to use the word which we removed the left bits.
+ if (word_start <= word_end) {
+ edge_word = bitmap_begin_[word_end];
+ }
+
+ // Bits that we trim off the right.
+ edge_word &= ~((static_cast<size_t>(kWordHighBitMask) >> right_bits) - 1);
+ uintptr_t ptr_base = IndexToOffset(word_end) + heap_begin_;
+ finger_visitor(reinterpret_cast<void*>(ptr_base + word_span));
+ while (edge_word != 0) {
+ const size_t shift = CLZ(edge_word);
+ mirror::Object* obj = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
+ visitor(obj);
+ edge_word ^= static_cast<size_t>(kWordHighBitMask) >> shift;
+ }
+}
+
+inline bool SpaceBitmap::Modify(const mirror::Object* obj, bool do_set) {
+ uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
+ DCHECK_GE(addr, heap_begin_);
+ const uintptr_t offset = addr - heap_begin_;
+ const size_t index = OffsetToIndex(offset);
+ const word mask = OffsetToMask(offset);
+ DCHECK_LT(index, bitmap_size_ / kWordSize) << " bitmap_size_ = " << bitmap_size_;
+ word* address = &bitmap_begin_[index];
+ word old_word = *address;
+ if (do_set) {
+ *address = old_word | mask;
+ } else {
+ *address = old_word & ~mask;
+ }
+ return (old_word & mask) != 0;
+}
+} // namespace art
+
+#endif // ART_SRC_GC_SPACE_BITMAP_INL_H_
diff --git a/src/gc/space_bitmap.cc b/src/gc/space_bitmap.cc
index 25fa672..d90c090 100644
--- a/src/gc/space_bitmap.cc
+++ b/src/gc/space_bitmap.cc
@@ -17,6 +17,11 @@
#include "heap_bitmap.h"
#include "base/logging.h"
+#include "mirror/class-inl.h"
+#include "mirror/field-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
+#include "space_bitmap-inl.h"
#include "UniquePtr.h"
#include "utils.h"
@@ -32,7 +37,7 @@
void SpaceSetMap::Walk(SpaceBitmap::Callback* callback, void* arg) {
for (Objects::iterator it = contained_.begin(); it != contained_.end(); ++it) {
- callback(const_cast<Object*>(*it), arg);
+ callback(const_cast<mirror::Object*>(*it), arg);
}
}
@@ -98,7 +103,7 @@
uintptr_t ptr_base = IndexToOffset(i) + heap_begin_;
do {
const size_t shift = CLZ(w);
- Object* obj = reinterpret_cast<Object*>(ptr_base + shift * kAlignment);
+ mirror::Object* obj = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
(*callback)(obj, arg);
w ^= static_cast<size_t>(kWordHighBitMask) >> shift;
} while (w != 0);
@@ -127,10 +132,10 @@
return;
}
- // TODO: rewrite the callbacks to accept a std::vector<Object*> rather than a Object**?
+ // TODO: rewrite the callbacks to accept a std::vector<mirror::Object*> rather than a mirror::Object**?
const size_t buffer_size = kWordSize * kBitsPerWord;
- Object* pointer_buf[buffer_size];
- Object** pb = &pointer_buf[0];
+ mirror::Object* pointer_buf[buffer_size];
+ mirror::Object** pb = &pointer_buf[0];
size_t start = OffsetToIndex(sweep_begin - live_bitmap.heap_begin_);
size_t end = OffsetToIndex(sweep_end - live_bitmap.heap_begin_ - 1);
CHECK_LT(end, live_bitmap.Size() / kWordSize);
@@ -143,7 +148,7 @@
do {
const size_t shift = CLZ(garbage);
garbage ^= static_cast<size_t>(kWordHighBitMask) >> shift;
- *pb++ = reinterpret_cast<Object*>(ptr_base + shift * kAlignment);
+ *pb++ = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
} while (garbage != 0);
// Make sure that there are always enough slots available for an
// entire word of one bits.
@@ -161,32 +166,32 @@
} // namespace art
// Support needed for in order traversal
-#include "object.h"
+#include "mirror/object.h"
#include "object_utils.h"
namespace art {
-static void WalkFieldsInOrder(SpaceBitmap* visited, SpaceBitmap::Callback* callback, Object* obj,
+static void WalkFieldsInOrder(SpaceBitmap* visited, SpaceBitmap::Callback* callback, mirror::Object* obj,
void* arg);
// Walk instance fields of the given Class. Separate function to allow recursion on the super
// class.
-static void WalkInstanceFields(SpaceBitmap* visited, SpaceBitmap::Callback* callback, Object* obj,
- Class* klass, void* arg)
+static void WalkInstanceFields(SpaceBitmap* visited, SpaceBitmap::Callback* callback, mirror::Object* obj,
+ mirror::Class* klass, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Visit fields of parent classes first.
- Class* super = klass->GetSuperClass();
+ mirror::Class* super = klass->GetSuperClass();
if (super != NULL) {
WalkInstanceFields(visited, callback, obj, super, arg);
}
// Walk instance fields
- ObjectArray<Field>* fields = klass->GetIFields();
+ mirror::ObjectArray<mirror::Field>* fields = klass->GetIFields();
if (fields != NULL) {
for (int32_t i = 0; i < fields->GetLength(); i++) {
- Field* field = fields->Get(i);
+ mirror::Field* field = fields->Get(i);
FieldHelper fh(field);
if (!fh.IsPrimitiveType()) {
- Object* value = field->GetObj(obj);
+ mirror::Object* value = field->GetObj(obj);
if (value != NULL) {
WalkFieldsInOrder(visited, callback, value, arg);
}
@@ -196,7 +201,7 @@
}
// For an unvisited object, visit it then all its children found via fields.
-static void WalkFieldsInOrder(SpaceBitmap* visited, SpaceBitmap::Callback* callback, Object* obj,
+static void WalkFieldsInOrder(SpaceBitmap* visited, SpaceBitmap::Callback* callback, mirror::Object* obj,
void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (visited->Test(obj)) {
@@ -206,17 +211,17 @@
(*callback)(obj, arg);
visited->Set(obj);
// Walk instance fields of all objects
- Class* klass = obj->GetClass();
+ mirror::Class* klass = obj->GetClass();
WalkInstanceFields(visited, callback, obj, klass, arg);
// Walk static fields of a Class
if (obj->IsClass()) {
- ObjectArray<Field>* fields = klass->GetSFields();
+ mirror::ObjectArray<mirror::Field>* fields = klass->GetSFields();
if (fields != NULL) {
for (int32_t i = 0; i < fields->GetLength(); i++) {
- Field* field = fields->Get(i);
+ mirror::Field* field = fields->Get(i);
FieldHelper fh(field);
if (!fh.IsPrimitiveType()) {
- Object* value = field->GetObj(NULL);
+ mirror::Object* value = field->GetObj(NULL);
if (value != NULL) {
WalkFieldsInOrder(visited, callback, value, arg);
}
@@ -225,10 +230,10 @@
}
} else if (obj->IsObjectArray()) {
// Walk elements of an object array
- ObjectArray<Object>* obj_array = obj->AsObjectArray<Object>();
+ mirror::ObjectArray<mirror::Object>* obj_array = obj->AsObjectArray<mirror::Object>();
int32_t length = obj_array->GetLength();
for (int32_t i = 0; i < length; i++) {
- Object* value = obj_array->Get(i);
+ mirror::Object* value = obj_array->Get(i);
if (value != NULL) {
WalkFieldsInOrder(visited, callback, value, arg);
}
@@ -251,7 +256,7 @@
uintptr_t ptr_base = IndexToOffset(i) + heap_begin_;
while (w != 0) {
const size_t shift = CLZ(w);
- Object* obj = reinterpret_cast<Object*>(ptr_base + shift * kAlignment);
+ mirror::Object* obj = reinterpret_cast<mirror::Object*>(ptr_base + shift * kAlignment);
WalkFieldsInOrder(visited.get(), callback, obj, arg);
w ^= static_cast<size_t>(kWordHighBitMask) >> shift;
}
diff --git a/src/gc/space_bitmap.h b/src/gc/space_bitmap.h
index dd2f47d..6bc06d6 100644
--- a/src/gc/space_bitmap.h
+++ b/src/gc/space_bitmap.h
@@ -14,35 +14,33 @@
* limitations under the License.
*/
-#ifndef ART_SRC_SPACE_BITMAP_H_
-#define ART_SRC_SPACE_BITMAP_H_
+#ifndef ART_SRC_GC_SPACE_BITMAP_H_
+#define ART_SRC_GC_SPACE_BITMAP_H_
+
+#include "locks.h"
+#include "globals.h"
+#include "mem_map.h"
+#include "UniquePtr.h"
#include <limits.h>
#include <set>
#include <stdint.h>
#include <vector>
-#include "base/logging.h"
-#include "cutils/atomic.h"
-#include "cutils/atomic-inline.h"
-#include "UniquePtr.h"
-#include "globals.h"
-#include "mem_map.h"
-#include "utils.h"
-
namespace art {
-
+namespace mirror {
class Object;
+} // namespace mirror
class SpaceBitmap {
public:
static const size_t kAlignment = 8;
- typedef void Callback(Object* obj, void* arg);
+ typedef void Callback(mirror::Object* obj, void* arg);
- typedef void ScanCallback(Object* obj, void* finger, void* arg);
+ typedef void ScanCallback(mirror::Object* obj, void* finger, void* arg);
- typedef void SweepCallback(size_t ptr_count, Object** ptrs, void* arg);
+ typedef void SweepCallback(size_t ptr_count, mirror::Object** ptrs, void* arg);
// Initialize a HeapBitmap so that it points to a bitmap large enough to cover a heap at
// heap_begin of heap_capacity bytes, where objects are guaranteed to be kAlignment-aligned.
@@ -66,44 +64,20 @@
return static_cast<uintptr_t>(kWordHighBitMask) >> ((offset_ / kAlignment) % kBitsPerWord);
}
- inline bool Set(const Object* obj) {
+ inline bool Set(const mirror::Object* obj) {
return Modify(obj, true);
}
- inline bool Clear(const Object* obj) {
+ inline bool Clear(const mirror::Object* obj) {
return Modify(obj, false);
}
// Returns true if the object was previously marked.
- inline bool AtomicTestAndSet(const Object* obj) {
- uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
- DCHECK_GE(addr, heap_begin_);
- const uintptr_t offset = addr - heap_begin_;
- const size_t index = OffsetToIndex(offset);
- const word mask = OffsetToMask(offset);
- word* const address = &bitmap_begin_[index];
- DCHECK_LT(index, bitmap_size_ / kWordSize) << " bitmap_size_ = " << bitmap_size_;
- word old_word;
- do {
- old_word = *address;
- // Fast path: The bit is already set.
- if ((old_word & mask) != 0) {
- return true;
- }
- } while (UNLIKELY(android_atomic_cas(old_word, old_word | mask, address) != 0));
- return false;
- }
+ bool AtomicTestAndSet(const mirror::Object* obj);
void Clear();
- inline bool Test(const Object* obj) const {
- uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
- DCHECK(HasAddress(obj)) << obj;
- DCHECK(bitmap_begin_ != NULL);
- DCHECK_GE(addr, heap_begin_);
- const uintptr_t offset = addr - heap_begin_;
- return (bitmap_begin_[OffsetToIndex(offset)] & OffsetToMask(offset)) != 0;
- }
+ bool Test(const mirror::Object* obj) const;
// Return true iff <obj> is within the range of pointers that this bitmap could potentially cover,
// even if a bit has not been set for it.
@@ -123,7 +97,7 @@
: bitmap_(bitmap) {
}
- void operator ()(Object* obj) const {
+ void operator ()(mirror::Object* obj) const {
bitmap_->Clear(obj);
}
private:
@@ -133,86 +107,21 @@
template <typename Visitor>
void VisitRange(uintptr_t visit_begin, uintptr_t visit_end, const Visitor& visitor) const {
for (; visit_begin < visit_end; visit_begin += kAlignment ) {
- visitor(reinterpret_cast<Object*>(visit_begin));
+ visitor(reinterpret_cast<mirror::Object*>(visit_begin));
}
}
template <typename Visitor, typename FingerVisitor>
void VisitMarkedRange(uintptr_t visit_begin, uintptr_t visit_end,
const Visitor& visitor, const FingerVisitor& finger_visitor) const
- EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_) {
- DCHECK_LT(visit_begin, visit_end);
-
- const size_t word_span = kAlignment * kBitsPerWord; // Equals IndexToOffset(1).
- const size_t bit_index_start = (visit_begin - heap_begin_) / kAlignment;
- const size_t bit_index_end = (visit_end - heap_begin_ - 1) / kAlignment;
-
- size_t word_start = bit_index_start / kBitsPerWord;
- size_t word_end = bit_index_end / kBitsPerWord;
- DCHECK_LT(word_end * kWordSize, Size());
-
- // Trim off left_bits of left bits.
- size_t edge_word = bitmap_begin_[word_start];
-
- // Handle bits on the left first as a special case
- size_t left_bits = bit_index_start & (kBitsPerWord - 1);
- if (left_bits != 0) {
- edge_word &= (1 << (kBitsPerWord - left_bits)) - 1;
- }
-
- // If word_start == word_end then handle this case at the same place we handle the right edge.
- if (edge_word != 0 && word_start < word_end) {
- uintptr_t ptr_base = IndexToOffset(word_start) + heap_begin_;
- finger_visitor(reinterpret_cast<void*>(ptr_base + word_span));
- do {
- const size_t shift = CLZ(edge_word);
- Object* obj = reinterpret_cast<Object*>(ptr_base + shift * kAlignment);
- visitor(obj);
- edge_word ^= static_cast<size_t>(kWordHighBitMask) >> shift;
- } while (edge_word != 0);
- }
- word_start++;
-
- for (size_t i = word_start; i < word_end; i++) {
- size_t w = bitmap_begin_[i];
- if (w != 0) {
- uintptr_t ptr_base = IndexToOffset(i) + heap_begin_;
- finger_visitor(reinterpret_cast<void*>(ptr_base + word_span));
- do {
- const size_t shift = CLZ(w);
- Object* obj = reinterpret_cast<Object*>(ptr_base + shift * kAlignment);
- visitor(obj);
- w ^= static_cast<size_t>(kWordHighBitMask) >> shift;
- } while (w != 0);
- }
- }
-
- // Handle the right edge, and also the left edge if both edges are on the same word.
- size_t right_bits = bit_index_end & (kBitsPerWord - 1);
-
- // If word_start == word_end then we need to use the word which we removed the left bits.
- if (word_start <= word_end) {
- edge_word = bitmap_begin_[word_end];
- }
-
- // Bits that we trim off the right.
- edge_word &= ~((static_cast<size_t>(kWordHighBitMask) >> right_bits) - 1);
- uintptr_t ptr_base = IndexToOffset(word_end) + heap_begin_;
- finger_visitor(reinterpret_cast<void*>(ptr_base + word_span));
- while (edge_word != 0) {
- const size_t shift = CLZ(edge_word);
- Object* obj = reinterpret_cast<Object*>(ptr_base + shift * kAlignment);
- visitor(obj);
- edge_word ^= static_cast<size_t>(kWordHighBitMask) >> shift;
- }
- }
+ EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void Walk(Callback* callback, void* arg)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
void InOrderWalk(Callback* callback, void* arg)
- SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_, Locks::mutator_lock_);
static void SweepWalk(const SpaceBitmap& live,
const SpaceBitmap& mark,
@@ -251,7 +160,7 @@
std::string GetName() const;
void SetName(const std::string& name);
- const void* GetObjectWordAddress(const Object* obj) const {
+ const void* GetObjectWordAddress(const mirror::Object* obj) const {
uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
const uintptr_t offset = addr - heap_begin_;
const size_t index = OffsetToIndex(offset);
@@ -265,22 +174,7 @@
heap_begin_(reinterpret_cast<uintptr_t>(heap_begin)),
name_(name) {}
- inline bool Modify(const Object* obj, bool do_set) {
- uintptr_t addr = reinterpret_cast<uintptr_t>(obj);
- DCHECK_GE(addr, heap_begin_);
- const uintptr_t offset = addr - heap_begin_;
- const size_t index = OffsetToIndex(offset);
- const word mask = OffsetToMask(offset);
- DCHECK_LT(index, bitmap_size_ / kWordSize) << " bitmap_size_ = " << bitmap_size_;
- word* address = &bitmap_begin_[index];
- word old_word = *address;
- if (do_set) {
- *address = old_word | mask;
- } else {
- *address = old_word & ~mask;
- }
- return (old_word & mask) != 0;
- }
+ bool Modify(const mirror::Object* obj, bool do_set);
// Backing storage for bitmap.
UniquePtr<MemMap> mem_map_;
@@ -302,17 +196,17 @@
// Like a bitmap except it keeps track of objects using sets.
class SpaceSetMap {
public:
- typedef std::set<const Object*> Objects;
+ typedef std::set<const mirror::Object*> Objects;
bool IsEmpty() const {
return contained_.empty();
}
- inline void Set(const Object* obj) {
+ inline void Set(const mirror::Object* obj) {
contained_.insert(obj);
}
- inline void Clear(const Object* obj) {
+ inline void Clear(const mirror::Object* obj) {
Objects::iterator found = contained_.find(obj);
if (found != contained_.end()) {
contained_.erase(found);
@@ -323,7 +217,7 @@
contained_.clear();
}
- inline bool Test(const Object* obj) const {
+ inline bool Test(const mirror::Object* obj) const {
return contained_.find(obj) != contained_.end();
}
@@ -357,4 +251,4 @@
} // namespace art
-#endif // ART_SRC_SPACE_BITMAP_H_
+#endif // ART_SRC_GC_SPACE_BITMAP_H_
diff --git a/src/gc/space_bitmap_test.cc b/src/gc/space_bitmap_test.cc
index a2f1afc..5a829e4 100644
--- a/src/gc/space_bitmap_test.cc
+++ b/src/gc/space_bitmap_test.cc
@@ -19,6 +19,7 @@
#include "common_test.h"
#include "dlmalloc.h"
#include "globals.h"
+#include "space_bitmap-inl.h"
#include "UniquePtr.h"
#include <stdint.h>
@@ -39,20 +40,20 @@
class BitmapVerify {
public:
- BitmapVerify(SpaceBitmap* bitmap, const Object* begin, const Object* end)
+ BitmapVerify(SpaceBitmap* bitmap, const mirror::Object* begin, const mirror::Object* end)
: bitmap_(bitmap),
begin_(begin),
end_(end) {}
- void operator ()(const Object* obj) {
+ void operator ()(const mirror::Object* obj) {
EXPECT_TRUE(obj >= begin_);
EXPECT_TRUE(obj <= end_);
EXPECT_TRUE(bitmap_->Test(obj) == ((reinterpret_cast<uintptr_t>(obj) & 0xF) != 0));
}
SpaceBitmap* bitmap_;
- const Object* begin_;
- const Object* end_;
+ const mirror::Object* begin_;
+ const mirror::Object* end_;
};
TEST_F(SpaceBitmapTest, ScanRange) {
@@ -65,7 +66,8 @@
// Set all the odd bits in the first BitsPerWord * 3 to one.
for (size_t j = 0;j < kBitsPerWord * 3; ++j) {
- const Object* obj = reinterpret_cast<Object*>(heap_begin + j * SpaceBitmap::kAlignment);
+ const mirror::Object* obj =
+ reinterpret_cast<mirror::Object*>(heap_begin + j * SpaceBitmap::kAlignment);
if (reinterpret_cast<uintptr_t>(obj) & 0xF) {
space_bitmap->Set(obj);
}
@@ -75,9 +77,11 @@
// This handles all the cases, having runs which start and end on the same word, and different
// words.
for (size_t i = 0; i < static_cast<size_t>(kBitsPerWord); ++i) {
- Object* start = reinterpret_cast<Object*>(heap_begin + i * SpaceBitmap::kAlignment);
+ mirror::Object* start =
+ reinterpret_cast<mirror::Object*>(heap_begin + i * SpaceBitmap::kAlignment);
for (size_t j = 0; j < static_cast<size_t>(kBitsPerWord * 2); ++j) {
- Object* end = reinterpret_cast<Object*>(heap_begin + (i + j) * SpaceBitmap::kAlignment);
+ mirror::Object* end =
+ reinterpret_cast<mirror::Object*>(heap_begin + (i + j) * SpaceBitmap::kAlignment);
BitmapVerify(space_bitmap.get(), start, end);
}
}
diff --git a/src/gc/space_test.cc b/src/gc/space_test.cc
index 2e03eae..372ec77 100644
--- a/src/gc/space_test.cc
+++ b/src/gc/space_test.cc
@@ -83,23 +83,23 @@
Thread* self = Thread::Current();
// Succeeds, fits without adjusting the footprint limit.
- Object* ptr1 = space->Alloc(self, 1 * MB);
+ mirror::Object* ptr1 = space->Alloc(self, 1 * MB);
EXPECT_TRUE(ptr1 != NULL);
// Fails, requires a higher footprint limit.
- Object* ptr2 = space->Alloc(self, 8 * MB);
+ mirror::Object* ptr2 = space->Alloc(self, 8 * MB);
EXPECT_TRUE(ptr2 == NULL);
// Succeeds, adjusts the footprint.
- Object* ptr3 = space->AllocWithGrowth(self, 8 * MB);
+ mirror::Object* ptr3 = space->AllocWithGrowth(self, 8 * MB);
EXPECT_TRUE(ptr3 != NULL);
// Fails, requires a higher footprint limit.
- Object* ptr4 = space->Alloc(self, 8 * MB);
+ mirror::Object* ptr4 = space->Alloc(self, 8 * MB);
EXPECT_TRUE(ptr4 == NULL);
// Also fails, requires a higher allowed footprint.
- Object* ptr5 = space->AllocWithGrowth(self, 8 * MB);
+ mirror::Object* ptr5 = space->AllocWithGrowth(self, 8 * MB);
EXPECT_TRUE(ptr5 == NULL);
// Release some memory.
@@ -151,23 +151,23 @@
Runtime::Current()->GetHeap()->AddSpace(space);
// Succeeds, fits without adjusting the footprint limit.
- Object* ptr1 = space->Alloc(self, 1 * MB);
+ mirror::Object* ptr1 = space->Alloc(self, 1 * MB);
EXPECT_TRUE(ptr1 != NULL);
// Fails, requires a higher footprint limit.
- Object* ptr2 = space->Alloc(self, 8 * MB);
+ mirror::Object* ptr2 = space->Alloc(self, 8 * MB);
EXPECT_TRUE(ptr2 == NULL);
// Succeeds, adjusts the footprint.
- Object* ptr3 = space->AllocWithGrowth(self, 8 * MB);
+ mirror::Object* ptr3 = space->AllocWithGrowth(self, 8 * MB);
EXPECT_TRUE(ptr3 != NULL);
// Fails, requires a higher footprint limit.
- Object* ptr4 = space->Alloc(self, 8 * MB);
+ mirror::Object* ptr4 = space->Alloc(self, 8 * MB);
EXPECT_TRUE(ptr4 == NULL);
// Also fails, requires a higher allowed footprint.
- Object* ptr5 = space->AllocWithGrowth(self, 8 * MB);
+ mirror::Object* ptr5 = space->AllocWithGrowth(self, 8 * MB);
EXPECT_TRUE(ptr5 == NULL);
// Release some memory.
@@ -194,7 +194,7 @@
Thread* self = Thread::Current();
// Succeeds, fits without adjusting the max allowed footprint.
- Object* lots_of_objects[1024];
+ mirror::Object* lots_of_objects[1024];
for (size_t i = 0; i < arraysize(lots_of_objects); i++) {
lots_of_objects[i] = space->Alloc(self, 16);
EXPECT_TRUE(lots_of_objects[i] != NULL);
@@ -252,7 +252,7 @@
// Fill the space with lots of small objects up to the growth limit
size_t max_objects = (growth_limit / (object_size > 0 ? object_size : 8)) + 1;
- UniquePtr<Object*[]> lots_of_objects(new Object*[max_objects]);
+ UniquePtr<mirror::Object*[]> lots_of_objects(new mirror::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();
@@ -269,7 +269,7 @@
alloc_size = 8;
}
}
- Object* object;
+ mirror::Object* object;
if (round <= 1) {
object = space->Alloc(self, alloc_size);
} else {
@@ -326,7 +326,7 @@
// Free some objects
for (size_t i = 0; i < last_object; i += free_increment) {
- Object* object = lots_of_objects.get()[i];
+ mirror::Object* object = lots_of_objects.get()[i];
if (object == NULL) {
continue;
}
@@ -347,7 +347,7 @@
}
// All memory was released, try a large allocation to check freed memory is being coalesced
- Object* large_object;
+ mirror::Object* large_object;
size_t three_quarters_space = (growth_limit / 2) + (growth_limit / 4);
if (round <= 1) {
large_object = space->Alloc(self, three_quarters_space);
diff --git a/src/gc/sticky_mark_sweep.cc b/src/gc/sticky_mark_sweep.cc
index 23196fd..988d4e7 100644
--- a/src/gc/sticky_mark_sweep.cc
+++ b/src/gc/sticky_mark_sweep.cc
@@ -14,47 +14,51 @@
* limitations under the License.
*/
+#include "heap.h"
#include "large_object_space.h"
#include "space.h"
#include "sticky_mark_sweep.h"
+#include "thread.h"
namespace art {
- StickyMarkSweep::StickyMarkSweep(Heap* heap, bool is_concurrent)
- : PartialMarkSweep(heap, is_concurrent) {
- cumulative_timings_.SetName(GetName());
- }
- StickyMarkSweep::~StickyMarkSweep() {
+StickyMarkSweep::StickyMarkSweep(Heap* heap, bool is_concurrent)
+ : PartialMarkSweep(heap, is_concurrent) {
+ cumulative_timings_.SetName(GetName());
+}
- }
+StickyMarkSweep::~StickyMarkSweep() {
- void StickyMarkSweep::BindBitmaps() {
- PartialMarkSweep::BindBitmaps();
+}
- Spaces& spaces = GetHeap()->GetSpaces();
- WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
- // For sticky GC, we want to bind the bitmaps of both the zygote space and the alloc space.
- // This lets us start with the mark bitmap of the previous garbage collection as the current
- // mark bitmap of the alloc space. After the sticky GC finishes, we then unbind the bitmaps,
- // making it so that the live bitmap of the alloc space is contains the newly marked objects
- // from the sticky GC.
- for (Spaces::iterator it = spaces.begin(); it != spaces.end(); ++it) {
- if ((*it)->GetGcRetentionPolicy() == kGcRetentionPolicyAlwaysCollect) {
- BindLiveToMarkBitmap(*it);
- }
+void StickyMarkSweep::BindBitmaps() {
+ PartialMarkSweep::BindBitmaps();
+
+ Spaces& spaces = GetHeap()->GetSpaces();
+ WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
+ // For sticky GC, we want to bind the bitmaps of both the zygote space and the alloc space.
+ // This lets us start with the mark bitmap of the previous garbage collection as the current
+ // mark bitmap of the alloc space. After the sticky GC finishes, we then unbind the bitmaps,
+ // making it so that the live bitmap of the alloc space is contains the newly marked objects
+ // from the sticky GC.
+ for (Spaces::iterator it = spaces.begin(); it != spaces.end(); ++it) {
+ if ((*it)->GetGcRetentionPolicy() == kGcRetentionPolicyAlwaysCollect) {
+ BindLiveToMarkBitmap(*it);
}
-
- GetHeap()->GetLargeObjectsSpace()->CopyLiveToMarked();
}
- void StickyMarkSweep::MarkReachableObjects() {
- DisableFinger();
- RecursiveMarkDirtyObjects(CardTable::kCardDirty - 1);
- }
+ GetHeap()->GetLargeObjectsSpace()->CopyLiveToMarked();
+}
- void StickyMarkSweep::Sweep(TimingLogger& timings, bool swap_bitmaps) {
- ObjectStack* live_stack = GetHeap()->GetLiveStack();
- SweepArray(timings_, live_stack, false);
- timings_.AddSplit("SweepArray");
- }
+void StickyMarkSweep::MarkReachableObjects() {
+ DisableFinger();
+ RecursiveMarkDirtyObjects(CardTable::kCardDirty - 1);
+}
+
+void StickyMarkSweep::Sweep(TimingLogger& timings, bool swap_bitmaps) {
+ ObjectStack* live_stack = GetHeap()->GetLiveStack();
+ SweepArray(timings_, live_stack, false);
+ timings_.AddSplit("SweepArray");
+}
+
} // namespace art
diff --git a/src/gc/sticky_mark_sweep.h b/src/gc/sticky_mark_sweep.h
index 8396bbe..41ab0cc 100644
--- a/src/gc/sticky_mark_sweep.h
+++ b/src/gc/sticky_mark_sweep.h
@@ -14,28 +14,15 @@
* limitations under the License.
*/
-#ifndef ART_SRC_STICKY_MARK_SWEEP_H_
-#define ART_SRC_STICKY_MARK_SWEEP_H_
+#ifndef ART_SRC_GC_STICKY_MARK_SWEEP_H_
+#define ART_SRC_GC_STICKY_MARK_SWEEP_H_
#include "base/macros.h"
#include "locks.h"
#include "partial_mark_sweep.h"
-#include "utils.h"
namespace art {
-class Barrier;
-class CheckObjectVisitor;
-class Class;
-class Heap;
-class MarkIfReachesAllocspaceVisitor;
-class ModUnionClearCardVisitor;
-class ModUnionVisitor;
-class ModUnionTableBitmap;
-class Object;
-class TimingLogger;
-class MarkStackChunk;
-
class StickyMarkSweep : public PartialMarkSweep {
public:
virtual GcType GetGcType() const {
@@ -60,4 +47,4 @@
} // namespace art
-#endif // ART_SRC_STICKY_MARK_SWEEP_H_
+#endif // ART_SRC_GC_STICKY_MARK_SWEEP_H_
diff --git a/src/heap.cc b/src/heap.cc
index 805d63c..5c96dec 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -27,15 +27,24 @@
#include "debugger.h"
#include "gc/atomic_stack.h"
#include "gc/card_table.h"
+#include "gc/card_table-inl.h"
#include "gc/heap_bitmap.h"
+#include "gc/heap_bitmap-inl.h"
#include "gc/large_object_space.h"
#include "gc/mark_sweep.h"
+#include "gc/mark_sweep-inl.h"
#include "gc/partial_mark_sweep.h"
+#include "gc/space_bitmap-inl.h"
#include "gc/sticky_mark_sweep.h"
#include "gc/mod_union_table.h"
+#include "gc/mod_union_table-inl.h"
#include "gc/space.h"
#include "image.h"
-#include "object.h"
+#include "mirror/class-inl.h"
+#include "mirror/field-inl.h"
+#include "mirror/object.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
#include "object_utils.h"
#include "os.h"
#include "ScopedLocalRef.h"
@@ -431,7 +440,7 @@
delete gc_complete_lock_;
}
-ContinuousSpace* Heap::FindSpaceFromObject(const Object* obj) const {
+ContinuousSpace* Heap::FindSpaceFromObject(const mirror::Object* obj) const {
// TODO: C++0x auto
for (Spaces::const_iterator it = spaces_.begin(); it != spaces_.end(); ++it) {
if ((*it)->Contains(obj)) {
@@ -465,13 +474,13 @@
}
}
-Object* Heap::AllocObject(Thread* self, Class* c, size_t byte_count) {
- DCHECK(c == NULL || (c->IsClassClass() && byte_count >= sizeof(Class)) ||
+mirror::Object* Heap::AllocObject(Thread* self, mirror::Class* c, size_t byte_count) {
+ DCHECK(c == NULL || (c->IsClassClass() && byte_count >= sizeof(mirror::Class)) ||
(c->IsVariableSize() || c->GetObjectSize() == byte_count) ||
strlen(ClassHelper(c).GetDescriptor()) == 0);
- DCHECK_GE(byte_count, sizeof(Object));
+ DCHECK_GE(byte_count, sizeof(mirror::Object));
- Object* obj = NULL;
+ mirror::Object* obj = NULL;
size_t size = 0;
uint64_t allocation_start = 0;
if (measure_allocation_time_) {
@@ -513,7 +522,7 @@
// concurrent_start_bytes_.
concurrent_start_bytes_ = std::numeric_limits<size_t>::max();
// The SirtRef is necessary since the calls in RequestConcurrentGC are a safepoint.
- SirtRef<Object> ref(self, obj);
+ SirtRef<mirror::Object> ref(self, obj);
RequestConcurrentGC(self);
}
VerifyObject(obj);
@@ -547,7 +556,7 @@
return NULL;
}
-bool Heap::IsHeapAddress(const Object* obj) {
+bool Heap::IsHeapAddress(const mirror::Object* obj) {
// Note: we deliberately don't take the lock here, and mustn't test anything that would
// require taking the lock.
if (obj == NULL) {
@@ -566,7 +575,7 @@
return large_object_space_->Contains(obj);
}
-bool Heap::IsLiveObjectLocked(const Object* obj) {
+bool Heap::IsLiveObjectLocked(const mirror::Object* obj) {
Locks::heap_bitmap_lock_->AssertReaderHeld(Thread::Current());
return IsHeapAddress(obj) && GetLiveBitmap()->Test(obj);
}
@@ -596,7 +605,7 @@
}
}
-void Heap::VerifyObjectBody(const Object* obj) {
+void Heap::VerifyObjectBody(const mirror::Object* obj) {
if (!IsAligned<kObjectAlignment>(obj)) {
LOG(FATAL) << "Object isn't aligned: " << obj;
}
@@ -618,8 +627,8 @@
// Ignore early dawn of the universe verifications
if (!VERIFY_OBJECT_FAST && GetObjectsAllocated() > 10) {
const byte* raw_addr = reinterpret_cast<const byte*>(obj) +
- Object::ClassOffset().Int32Value();
- const Class* c = *reinterpret_cast<Class* const *>(raw_addr);
+ mirror::Object::ClassOffset().Int32Value();
+ const mirror::Class* c = *reinterpret_cast<mirror::Class* const *>(raw_addr);
if (c == NULL) {
LOG(FATAL) << "Null class in object: " << obj;
} else if (!IsAligned<kObjectAlignment>(c)) {
@@ -630,15 +639,15 @@
// Check obj.getClass().getClass() == obj.getClass().getClass().getClass()
// Note: we don't use the accessors here as they have internal sanity checks
// that we don't want to run
- raw_addr = reinterpret_cast<const byte*>(c) + Object::ClassOffset().Int32Value();
- const Class* c_c = *reinterpret_cast<Class* const *>(raw_addr);
- raw_addr = reinterpret_cast<const byte*>(c_c) + Object::ClassOffset().Int32Value();
- const Class* c_c_c = *reinterpret_cast<Class* const *>(raw_addr);
+ raw_addr = reinterpret_cast<const byte*>(c) + mirror::Object::ClassOffset().Int32Value();
+ const mirror::Class* c_c = *reinterpret_cast<mirror::Class* const *>(raw_addr);
+ raw_addr = reinterpret_cast<const byte*>(c_c) + mirror::Object::ClassOffset().Int32Value();
+ const mirror::Class* c_c_c = *reinterpret_cast<mirror::Class* const *>(raw_addr);
CHECK_EQ(c_c, c_c_c);
}
}
-void Heap::VerificationCallback(Object* obj, void* arg) {
+void Heap::VerificationCallback(mirror::Object* obj, void* arg) {
DCHECK(obj != NULL);
reinterpret_cast<Heap*>(arg)->VerifyObjectBody(obj);
}
@@ -648,7 +657,7 @@
GetLiveBitmap()->Walk(Heap::VerificationCallback, this);
}
-void Heap::RecordAllocation(size_t size, Object* obj) {
+void Heap::RecordAllocation(size_t size, mirror::Object* obj) {
DCHECK(obj != NULL);
DCHECK_GT(size, 0u);
num_bytes_allocated_ += size;
@@ -687,7 +696,7 @@
}
}
-Object* Heap::TryToAllocate(Thread* self, AllocSpace* space, size_t alloc_size, bool grow) {
+mirror::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 > max_allowed_footprint_) {
// max_allowed_footprint_ <= growth_limit_ so it is safe to check in here.
@@ -711,13 +720,13 @@
return space->Alloc(self, alloc_size);
}
-Object* Heap::Allocate(Thread* self, AllocSpace* space, size_t alloc_size) {
+mirror::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.
DCHECK_EQ(self->GetState(), kRunnable);
self->AssertThreadSuspensionIsAllowable();
- Object* ptr = TryToAllocate(self, space, alloc_size, false);
+ mirror::Object* ptr = TryToAllocate(self, space, alloc_size, false);
if (ptr != NULL) {
return ptr;
}
@@ -838,14 +847,14 @@
class InstanceCounter {
public:
- InstanceCounter(const std::vector<Class*>& classes, bool use_is_assignable_from, uint64_t* counts)
+ InstanceCounter(const std::vector<mirror::Class*>& classes, bool use_is_assignable_from, uint64_t* counts)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: classes_(classes), use_is_assignable_from_(use_is_assignable_from), counts_(counts) {
}
- void operator()(const Object* o) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ void operator()(const mirror::Object* o) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
for (size_t i = 0; i < classes_.size(); ++i) {
- const Class* instance_class = o->GetClass();
+ const mirror::Class* instance_class = o->GetClass();
if (use_is_assignable_from_) {
if (instance_class != NULL && classes_[i]->IsAssignableFrom(instance_class)) {
++counts_[i];
@@ -859,14 +868,14 @@
}
private:
- const std::vector<Class*>& classes_;
+ const std::vector<mirror::Class*>& classes_;
bool use_is_assignable_from_;
uint64_t* const counts_;
DISALLOW_COPY_AND_ASSIGN(InstanceCounter);
};
-void Heap::CountInstances(const std::vector<Class*>& classes, bool use_is_assignable_from,
+void Heap::CountInstances(const std::vector<mirror::Class*>& classes, bool use_is_assignable_from,
uint64_t* counts) {
// We only want reachable instances, so do a GC. This also ensures that the alloc stack
// is empty, so the live bitmap is the only place we need to look.
@@ -882,29 +891,30 @@
class InstanceCollector {
public:
- InstanceCollector(Class* c, int32_t max_count, std::vector<Object*>& instances)
+ InstanceCollector(mirror::Class* c, int32_t max_count, std::vector<mirror::Object*>& instances)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: class_(c), max_count_(max_count), instances_(instances) {
}
- void operator()(const Object* o) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- const Class* instance_class = o->GetClass();
+ void operator()(const mirror::Object* o) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ const mirror::Class* instance_class = o->GetClass();
if (instance_class == class_) {
if (max_count_ == 0 || instances_.size() < max_count_) {
- instances_.push_back(const_cast<Object*>(o));
+ instances_.push_back(const_cast<mirror::Object*>(o));
}
}
}
private:
- Class* class_;
+ mirror::Class* class_;
uint32_t max_count_;
- std::vector<Object*>& instances_;
+ std::vector<mirror::Object*>& instances_;
DISALLOW_COPY_AND_ASSIGN(InstanceCollector);
};
-void Heap::GetInstances(Class* c, int32_t max_count, std::vector<Object*>& instances) {
+void Heap::GetInstances(mirror::Class* c, int32_t max_count,
+ std::vector<mirror::Object*>& instances) {
// We only want reachable instances, so do a GC. This also ensures that the alloc stack
// is empty, so the live bitmap is the only place we need to look.
Thread* self = Thread::Current();
@@ -919,7 +929,8 @@
class ReferringObjectsFinder {
public:
- ReferringObjectsFinder(Object* object, int32_t max_count, std::vector<Object*>& referring_objects)
+ ReferringObjectsFinder(mirror::Object* object, int32_t max_count,
+ std::vector<mirror::Object*>& referring_objects)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: object_(object), max_count_(max_count), referring_objects_(referring_objects) {
}
@@ -927,27 +938,28 @@
// For bitmap Visit.
// TODO: Fix lock analysis to not use NO_THREAD_SAFETY_ANALYSIS, requires support for
// annotalysis on visitors.
- void operator()(const Object* o) const NO_THREAD_SAFETY_ANALYSIS {
+ void operator()(const mirror::Object* o) const NO_THREAD_SAFETY_ANALYSIS {
MarkSweep::VisitObjectReferences(o, *this);
}
// For MarkSweep::VisitObjectReferences.
- void operator ()(const Object* referrer, const Object* object, const MemberOffset&, bool) const {
+ void operator ()(const mirror::Object* referrer, const mirror::Object* object,
+ const MemberOffset&, bool) const {
if (object == object_ && (max_count_ == 0 || referring_objects_.size() < max_count_)) {
- referring_objects_.push_back(const_cast<Object*>(referrer));
+ referring_objects_.push_back(const_cast<mirror::Object*>(referrer));
}
}
private:
- Object* object_;
+ mirror::Object* object_;
uint32_t max_count_;
- std::vector<Object*>& referring_objects_;
+ std::vector<mirror::Object*>& referring_objects_;
DISALLOW_COPY_AND_ASSIGN(ReferringObjectsFinder);
};
-void Heap::GetReferringObjects(Object* o, int32_t max_count,
- std::vector<Object*>& referring_objects) {
+void Heap::GetReferringObjects(mirror::Object* o, int32_t max_count,
+ std::vector<mirror::Object*>& referring_objects) {
// We only want reachable instances, so do a GC. This also ensures that the alloc stack
// is empty, so the live bitmap is the only place we need to look.
Thread* self = Thread::Current();
@@ -1026,9 +1038,9 @@
}
void Heap::MarkAllocStack(SpaceBitmap* bitmap, SpaceSetMap* large_objects, ObjectStack* stack) {
- Object** limit = stack->End();
- for (Object** it = stack->Begin(); it != limit; ++it) {
- const Object* obj = *it;
+ mirror::Object** limit = stack->End();
+ for (mirror::Object** it = stack->Begin(); it != limit; ++it) {
+ const mirror::Object* obj = *it;
DCHECK(obj != NULL);
if (LIKELY(bitmap->HasAddress(obj))) {
bitmap->Set(obj);
@@ -1039,9 +1051,9 @@
}
void Heap::UnMarkAllocStack(SpaceBitmap* bitmap, SpaceSetMap* large_objects, ObjectStack* stack) {
- Object** limit = stack->End();
- for (Object** it = stack->Begin(); it != limit; ++it) {
- const Object* obj = *it;
+ mirror::Object** limit = stack->End();
+ for (mirror::Object** it = stack->Begin(); it != limit; ++it) {
+ const mirror::Object* obj = *it;
DCHECK(obj != NULL);
if (LIKELY(bitmap->HasAddress(obj))) {
bitmap->Clear(obj);
@@ -1187,8 +1199,8 @@
timings.AddSplit("MarkImageToAllocSpaceReferences");
}
-void Heap::RootMatchesObjectVisitor(const Object* root, void* arg) {
- Object* obj = reinterpret_cast<Object*>(arg);
+void Heap::RootMatchesObjectVisitor(const mirror::Object* root, void* arg) {
+ mirror::Object* obj = reinterpret_cast<mirror::Object*>(arg);
if (root == obj) {
LOG(INFO) << "Object " << obj << " is a root";
}
@@ -1196,7 +1208,7 @@
class ScanVisitor {
public:
- void operator ()(const Object* obj) const {
+ void operator ()(const mirror::Object* obj) const {
LOG(INFO) << "Would have rescanned object " << obj;
}
};
@@ -1212,8 +1224,9 @@
// TODO: Fix lock analysis to not use NO_THREAD_SAFETY_ANALYSIS, requires support for smarter
// analysis.
- void operator ()(const Object* obj, const Object* ref, const MemberOffset& /* offset */,
- bool /* is_static */) const NO_THREAD_SAFETY_ANALYSIS {
+ void operator ()(const mirror::Object* obj, const mirror::Object* ref,
+ const MemberOffset& /* offset */, bool /* is_static */) const
+ NO_THREAD_SAFETY_ANALYSIS {
// Verify that the reference is live.
if (ref != NULL && !IsLive(ref)) {
CardTable* card_table = heap_->GetCardTable();
@@ -1260,7 +1273,7 @@
}
}
- bool IsLive(const Object* obj) const NO_THREAD_SAFETY_ANALYSIS {
+ bool IsLive(const mirror::Object* obj) const NO_THREAD_SAFETY_ANALYSIS {
if (heap_->GetLiveBitmap()->Test(obj)) {
return true;
}
@@ -1284,7 +1297,7 @@
}
- void operator ()(const Object* obj) const
+ void operator ()(const mirror::Object* obj) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_) {
VerifyReferenceVisitor visitor(heap_, const_cast<bool*>(&failed_));
MarkSweep::VisitObjectReferences(obj, visitor);
@@ -1328,8 +1341,8 @@
// TODO: Fix lock analysis to not use NO_THREAD_SAFETY_ANALYSIS, requires support for
// annotalysis on visitors.
- void operator ()(const Object* obj, const Object* ref, const MemberOffset& offset,
- bool is_static) const NO_THREAD_SAFETY_ANALYSIS {
+ void operator ()(const mirror::Object* obj, const mirror::Object* ref, const MemberOffset& offset,
+ bool is_static) const NO_THREAD_SAFETY_ANALYSIS {
// Filter out class references since changing an object's class does not mark the card as dirty.
// Also handles large objects, since the only reference they hold is a class reference.
if (ref != NULL && !ref->IsClass()) {
@@ -1355,12 +1368,13 @@
// Print which field of the object is dead.
if (!obj->IsObjectArray()) {
- const Class* klass = is_static ? obj->AsClass() : obj->GetClass();
+ const mirror::Class* klass = is_static ? obj->AsClass() : obj->GetClass();
CHECK(klass != NULL);
- const ObjectArray<Field>* fields = is_static ? klass->GetSFields() : klass->GetIFields();
+ const mirror::ObjectArray<mirror::Field>* fields = is_static ? klass->GetSFields()
+ : klass->GetIFields();
CHECK(fields != NULL);
for (int32_t i = 0; i < fields->GetLength(); ++i) {
- const Field* cur = fields->Get(i);
+ const mirror::Field* cur = fields->Get(i);
if (cur->GetOffset().Int32Value() == offset.Int32Value()) {
LOG(ERROR) << (is_static ? "Static " : "") << "field in the live stack is "
<< PrettyField(cur);
@@ -1368,7 +1382,8 @@
}
}
} else {
- const ObjectArray<Object>* object_array = obj->AsObjectArray<Object>();
+ const mirror::ObjectArray<mirror::Object>* object_array =
+ obj->AsObjectArray<mirror::Object>();
for (int32_t i = 0; i < object_array->GetLength(); ++i) {
if (object_array->Get(i) == ref) {
LOG(ERROR) << (is_static ? "Static " : "") << "obj[" << i << "] = ref";
@@ -1395,7 +1410,7 @@
}
- void operator ()(const Object* obj) const
+ void operator ()(const mirror::Object* obj) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_, Locks::heap_bitmap_lock_) {
VerifyReferenceCardVisitor visitor(heap_, const_cast<bool*>(&failed_));
MarkSweep::VisitObjectReferences(obj, visitor);
@@ -1419,7 +1434,7 @@
GetLiveBitmap()->Visit(visitor);
// We can verify objects in the live stack since none of these should reference dead objects.
- for (Object** it = live_stack_->Begin(); it != live_stack_->End(); ++it) {
+ for (mirror::Object** it = live_stack_->Begin(); it != live_stack_->End(); ++it) {
visitor(*it);
}
@@ -1636,34 +1651,36 @@
CHECK_NE(finalizer_reference_zombie_offset_.Uint32Value(), 0U);
}
-Object* Heap::GetReferenceReferent(Object* reference) {
+mirror::Object* Heap::GetReferenceReferent(mirror::Object* reference) {
DCHECK(reference != NULL);
DCHECK_NE(reference_referent_offset_.Uint32Value(), 0U);
- return reference->GetFieldObject<Object*>(reference_referent_offset_, true);
+ return reference->GetFieldObject<mirror::Object*>(reference_referent_offset_, true);
}
-void Heap::ClearReferenceReferent(Object* reference) {
+void Heap::ClearReferenceReferent(mirror::Object* reference) {
DCHECK(reference != NULL);
DCHECK_NE(reference_referent_offset_.Uint32Value(), 0U);
reference->SetFieldObject(reference_referent_offset_, NULL, true);
}
// Returns true if the reference object has not yet been enqueued.
-bool Heap::IsEnqueuable(const Object* ref) {
+bool Heap::IsEnqueuable(const mirror::Object* ref) {
DCHECK(ref != NULL);
- const Object* queue = ref->GetFieldObject<Object*>(reference_queue_offset_, false);
- const Object* queue_next = ref->GetFieldObject<Object*>(reference_queueNext_offset_, false);
+ const mirror::Object* queue =
+ ref->GetFieldObject<mirror::Object*>(reference_queue_offset_, false);
+ const mirror::Object* queue_next =
+ ref->GetFieldObject<mirror::Object*>(reference_queueNext_offset_, false);
return (queue != NULL) && (queue_next == NULL);
}
-void Heap::EnqueueReference(Object* ref, Object** cleared_reference_list) {
+void Heap::EnqueueReference(mirror::Object* ref, mirror::Object** cleared_reference_list) {
DCHECK(ref != NULL);
- CHECK(ref->GetFieldObject<Object*>(reference_queue_offset_, false) != NULL);
- CHECK(ref->GetFieldObject<Object*>(reference_queueNext_offset_, false) == NULL);
+ CHECK(ref->GetFieldObject<mirror::Object*>(reference_queue_offset_, false) != NULL);
+ CHECK(ref->GetFieldObject<mirror::Object*>(reference_queueNext_offset_, false) == NULL);
EnqueuePendingReference(ref, cleared_reference_list);
}
-void Heap::EnqueuePendingReference(Object* ref, Object** list) {
+void Heap::EnqueuePendingReference(mirror::Object* ref, mirror::Object** list) {
DCHECK(ref != NULL);
DCHECK(list != NULL);
@@ -1673,17 +1690,19 @@
ref->SetFieldObject(reference_pendingNext_offset_, ref, false);
*list = ref;
} else {
- Object* head = (*list)->GetFieldObject<Object*>(reference_pendingNext_offset_, false);
+ mirror::Object* head =
+ (*list)->GetFieldObject<mirror::Object*>(reference_pendingNext_offset_, false);
ref->SetFieldObject(reference_pendingNext_offset_, head, false);
(*list)->SetFieldObject(reference_pendingNext_offset_, ref, false);
}
}
-Object* Heap::DequeuePendingReference(Object** list) {
+mirror::Object* Heap::DequeuePendingReference(mirror::Object** list) {
DCHECK(list != NULL);
DCHECK(*list != NULL);
- Object* head = (*list)->GetFieldObject<Object*>(reference_pendingNext_offset_, false);
- Object* ref;
+ mirror::Object* head = (*list)->GetFieldObject<mirror::Object*>(reference_pendingNext_offset_,
+ false);
+ mirror::Object* ref;
// Note: the following code is thread-safe because it is only called from ProcessReferences which
// is single threaded.
@@ -1691,7 +1710,8 @@
ref = *list;
*list = NULL;
} else {
- Object* next = head->GetFieldObject<Object*>(reference_pendingNext_offset_, false);
+ mirror::Object* next = head->GetFieldObject<mirror::Object*>(reference_pendingNext_offset_,
+ false);
(*list)->SetFieldObject(reference_pendingNext_offset_, next, false);
ref = head;
}
@@ -1699,7 +1719,7 @@
return ref;
}
-void Heap::AddFinalizerReference(Thread* self, Object* object) {
+void Heap::AddFinalizerReference(Thread* self, mirror::Object* object) {
ScopedObjectAccess soa(self);
JValue args[1];
args[0].SetL(object);
@@ -1731,7 +1751,7 @@
return concurrent_min_free_;
}
-void Heap::EnqueueClearedReferences(Object** cleared) {
+void Heap::EnqueueClearedReferences(mirror::Object** cleared) {
DCHECK(cleared != NULL);
if (*cleared != NULL) {
// When a runtime isn't started there are no reference queues to care about so ignore.
diff --git a/src/heap.h b/src/heap.h
index b7fc34d..9981f83 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -24,6 +24,7 @@
#include "atomic_integer.h"
#include "gc/atomic_stack.h"
#include "gc/card_table.h"
+#include "gc/gc_type.h"
#include "gc/heap_bitmap.h"
#include "globals.h"
#include "gtest/gtest.h"
@@ -39,9 +40,11 @@
#define VERIFY_OBJECT_FAST 1
namespace art {
-
-class AllocSpace;
+namespace mirror {
class Class;
+class Object;
+} // namespace mirror
+class AllocSpace;
class ConditionVariable;
class DlMallocSpace;
class GarbageCollector;
@@ -51,14 +54,12 @@
class MarkSweep;
class ModUnionTable;
class Mutex;
-class Object;
class Space;
class SpaceTest;
class StackVisitor;
class Thread;
class TimingLogger;
-typedef AtomicStack<Object*> ObjectStack;
typedef std::vector<ContinuousSpace*> Spaces;
class AgeCardVisitor {
@@ -72,21 +73,6 @@
}
};
-// The ordering of the enum matters, it is used to determine which GCs are run first.
-enum GcType {
- // No Gc
- kGcTypeNone,
- // Sticky mark bits "generational" GC.
- kGcTypeSticky,
- // Partial GC, over only the alloc space.
- kGcTypePartial,
- // Full GC
- kGcTypeFull,
- // Number of different Gc types.
- kGcTypeMax,
-};
-std::ostream& operator<<(std::ostream& os, const GcType& policy);
-
enum GcCause {
kGcCauseForAlloc,
kGcCauseBackground,
@@ -107,11 +93,6 @@
// Used so that we don't overflow the allocation time atomic integer.
static const size_t kTimeAdjust = 1024;
- typedef void (RootVisitor)(const Object* root, void* arg);
- typedef void (VerifyRootVisitor)(const Object* root, void* arg, size_t vreg,
- const StackVisitor* visitor);
- typedef bool (IsMarkedTester)(const Object* object, void* arg);
-
// Create a heap with the requested sizes. The possible empty
// image_file_names names specify Spaces to load based on
// ImageWriter output.
@@ -122,19 +103,19 @@
~Heap();
// Allocates and initializes storage for an object instance.
- Object* AllocObject(Thread* self, Class* klass, size_t num_bytes)
+ mirror::Object* AllocObject(Thread* self, mirror::Class* klass, size_t num_bytes)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Check sanity of given reference. Requires the heap lock.
#if VERIFY_OBJECT_ENABLED
- void VerifyObject(const Object* o);
+ void VerifyObject(const mirror::Object* o);
#else
- void VerifyObject(const Object*) {}
+ void VerifyObject(const mirror::Object*) {}
#endif
// Check sanity of all live references. Requires the heap lock.
void VerifyHeap() LOCKS_EXCLUDED(Locks::heap_bitmap_lock_);
- static void RootMatchesObjectVisitor(const Object* root, void* arg);
+ static void RootMatchesObjectVisitor(const mirror::Object* root, void* arg);
bool VerifyHeapReferences()
EXCLUSIVE_LOCKS_REQUIRED(Locks::heap_bitmap_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -145,11 +126,11 @@
// A weaker test than IsLiveObject or VerifyObject that doesn't require the heap lock,
// and doesn't abort on error, allowing the caller to report more
// meaningful diagnostics.
- bool IsHeapAddress(const Object* obj);
+ bool IsHeapAddress(const mirror::Object* obj);
// Returns true if 'obj' is a live heap object, false otherwise (including for invalid addresses).
// Requires the heap lock to be held.
- bool IsLiveObjectLocked(const Object* obj)
+ bool IsLiveObjectLocked(const mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
// Initiates an explicit garbage collection.
@@ -169,16 +150,16 @@
// Implements VMDebug.countInstancesOfClass and JDWP VM_InstanceCount.
// The boolean decides whether to use IsAssignableFrom or == when comparing classes.
- void CountInstances(const std::vector<Class*>& classes, bool use_is_assignable_from,
+ void CountInstances(const std::vector<mirror::Class*>& classes, bool use_is_assignable_from,
uint64_t* counts)
LOCKS_EXCLUDED(Locks::heap_bitmap_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Implements JDWP RT_Instances.
- void GetInstances(Class* c, int32_t max_count, std::vector<Object*>& instances)
+ void GetInstances(mirror::Class* c, int32_t max_count, std::vector<mirror::Object*>& instances)
LOCKS_EXCLUDED(Locks::heap_bitmap_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Implements JDWP OR_ReferringObjects.
- void GetReferringObjects(Object* o, int32_t max_count, std::vector<Object*>& referring_objects)
+ void GetReferringObjects(mirror::Object* o, int32_t max_count, std::vector<mirror::Object*>& referring_objects)
LOCKS_EXCLUDED(Locks::heap_bitmap_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -218,15 +199,15 @@
MemberOffset reference_pendingNext_offset,
MemberOffset finalizer_reference_zombie_offset);
- Object* GetReferenceReferent(Object* reference);
- void ClearReferenceReferent(Object* reference) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::Object* GetReferenceReferent(mirror::Object* reference);
+ void ClearReferenceReferent(mirror::Object* reference) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Returns true if the reference object has not yet been enqueued.
- bool IsEnqueuable(const Object* ref);
- void EnqueueReference(Object* ref, Object** list) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void EnqueuePendingReference(Object* ref, Object** list)
+ bool IsEnqueuable(const mirror::Object* ref);
+ void EnqueueReference(mirror::Object* ref, mirror::Object** list) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void EnqueuePendingReference(mirror::Object* ref, mirror::Object** list)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Object* DequeuePendingReference(Object** list) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::Object* DequeuePendingReference(mirror::Object** list) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
MemberOffset GetReferencePendingNextOffset() {
DCHECK_NE(reference_pendingNext_offset_.Uint32Value(), 0U);
@@ -257,12 +238,12 @@
// Must be called if a field of an Object in the heap changes, and before any GC safe-point.
// The call is not needed if NULL is stored in the field.
- void WriteBarrierField(const Object* dst, MemberOffset /*offset*/, const Object* /*new_value*/) {
+ void WriteBarrierField(const mirror::Object* dst, MemberOffset /*offset*/, const mirror::Object* /*new_value*/) {
card_table_->MarkCard(dst);
}
// Write barrier for array operations that update many field positions
- void WriteBarrierArray(const Object* dst, int /*start_offset*/,
+ void WriteBarrierArray(const mirror::Object* dst, int /*start_offset*/,
size_t /*length TODO: element_count or byte_count?*/) {
card_table_->MarkCard(dst);
}
@@ -271,7 +252,7 @@
return card_table_.get();
}
- void AddFinalizerReference(Thread* self, Object* object);
+ void AddFinalizerReference(Thread* self, mirror::Object* object);
size_t GetBytesAllocated() const;
size_t GetObjectsAllocated() const;
@@ -293,7 +274,7 @@
// Functions for getting the bitmap which corresponds to an object's address.
// This is probably slow, TODO: use better data structure like binary tree .
- ContinuousSpace* FindSpaceFromObject(const Object*) const;
+ ContinuousSpace* FindSpaceFromObject(const mirror::Object*) const;
void DumpForSigQuit(std::ostream& os);
@@ -354,22 +335,22 @@
private:
// Allocates uninitialized storage. Passing in a null space tries to place the object in the
// large object space.
- Object* Allocate(Thread* self, AllocSpace* space, size_t num_bytes)
+ mirror::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(Thread* self, AllocSpace* space, size_t alloc_size, bool grow)
+ mirror::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_);
// Pushes a list of cleared references out to the managed heap.
- void EnqueueClearedReferences(Object** cleared_references);
+ void EnqueueClearedReferences(mirror::Object** cleared_references);
void RequestHeapTrim() LOCKS_EXCLUDED(Locks::runtime_shutdown_lock_);
void RequestConcurrentGC(Thread* self) LOCKS_EXCLUDED(Locks::runtime_shutdown_lock_);
- void RecordAllocation(size_t size, Object* object)
+ void RecordAllocation(size_t size, mirror::Object* object)
LOCKS_EXCLUDED(GlobalSynchronization::heap_bitmap_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -395,9 +376,9 @@
// No thread saftey analysis since we call this everywhere and it is impossible to find a proper
// lock ordering for it.
- void VerifyObjectBody(const Object *obj) NO_THREAD_SAFETY_ANALYSIS;
+ void VerifyObjectBody(const mirror::Object *obj) NO_THREAD_SAFETY_ANALYSIS;
- static void VerificationCallback(Object* obj, void* arg)
+ static void VerificationCallback(mirror::Object* obj, void* arg)
SHARED_LOCKS_REQUIRED(GlobalSychronization::heap_bitmap_lock_);
// Swap the allocation stack with the live stack.
diff --git a/src/heap_test.cc b/src/heap_test.cc
index 6db7416..79cc835 100644
--- a/src/heap_test.cc
+++ b/src/heap_test.cc
@@ -15,6 +15,11 @@
*/
#include "common_test.h"
+#include "gc/card_table-inl.h"
+#include "gc/space_bitmap-inl.h"
+#include "mirror/class-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
#include "sirt_ref.h"
namespace art {
@@ -37,12 +42,12 @@
ScopedObjectAccess soa(Thread::Current());
// garbage is created during ClassLinker::Init
- Class* c = class_linker_->FindSystemClass("[Ljava/lang/Object;");
+ mirror::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(soa.Self(), c, 2048));
+ SirtRef<mirror::ObjectArray<mirror::Object> > array(soa.Self(),
+ mirror::ObjectArray<mirror::Object>::Alloc(soa.Self(), c, 2048));
for (size_t j = 0; j < 2048; ++j) {
- array->Set(j, String::AllocFromModifiedUtf8(soa.Self(), "hello, world!"));
+ array->Set(j, mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello, world!"));
}
}
}
@@ -53,7 +58,7 @@
byte* heap_begin = reinterpret_cast<byte*>(0x1000);
const size_t heap_capacity = SpaceBitmap::kAlignment * (sizeof(intptr_t) * 8 + 1);
UniquePtr<SpaceBitmap> bitmap(SpaceBitmap::Create("test-bitmap", heap_begin, heap_capacity));
- bitmap->Set(reinterpret_cast<const Object*>(&heap_begin[heap_capacity - SpaceBitmap::kAlignment]));
+ bitmap->Set(reinterpret_cast<const mirror::Object*>(&heap_begin[heap_capacity - SpaceBitmap::kAlignment]));
}
} // namespace art
diff --git a/src/hprof/hprof.cc b/src/hprof/hprof.cc
index c0e73bc..e0a4c05 100644
--- a/src/hprof/hprof.cc
+++ b/src/hprof/hprof.cc
@@ -44,7 +44,11 @@
#include "debugger.h"
#include "globals.h"
#include "heap.h"
-#include "object.h"
+#include "mirror/class.h"
+#include "mirror/class-inl.h"
+#include "mirror/field.h"
+#include "mirror/field-inl.h"
+#include "mirror/object-inl.h"
#include "object_utils.h"
#include "os.h"
#include "safe_map.h"
@@ -165,8 +169,8 @@
typedef HprofId HprofStringId;
typedef HprofId HprofObjectId;
typedef HprofId HprofClassObjectId;
-typedef std::set<Class*> ClassSet;
-typedef std::set<Class*>::iterator ClassSetIterator;
+typedef std::set<mirror::Class*> ClassSet;
+typedef std::set<mirror::Class*>::iterator ClassSetIterator;
typedef SafeMap<std::string, size_t> StringMap;
typedef SafeMap<std::string, size_t>::iterator StringMapIterator;
@@ -480,14 +484,14 @@
}
private:
- static void RootVisitor(const Object* obj, void* arg)
+ static void RootVisitor(const mirror::Object* obj, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK(arg != NULL);
Hprof* hprof = reinterpret_cast<Hprof*>(arg);
hprof->VisitRoot(obj);
}
- static void HeapBitmapCallback(Object* obj, void* arg)
+ static void HeapBitmapCallback(mirror::Object* obj, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK(obj != NULL);
CHECK(arg != NULL);
@@ -495,9 +499,9 @@
hprof->DumpHeapObject(obj);
}
- void VisitRoot(const Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void VisitRoot(const mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- int DumpHeapObject(Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ int DumpHeapObject(mirror::Object* obj) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void Finish() {
}
@@ -507,7 +511,7 @@
uint32_t nextSerialNumber = 1;
for (ClassSetIterator it = classes_.begin(); it != classes_.end(); ++it) {
- const Class* c = *it;
+ const mirror::Class* c = *it;
CHECK(c != NULL);
int err = current_record_.StartNewRecord(header_fp_, HPROF_TAG_LOAD_CLASS, HPROF_TIME);
@@ -567,9 +571,9 @@
current_heap_ = HPROF_HEAP_DEFAULT;
}
- int MarkRootObject(const Object* obj, jobject jniObj);
+ int MarkRootObject(const mirror::Object* obj, jobject jniObj);
- HprofClassObjectId LookupClassId(Class* c)
+ HprofClassObjectId LookupClassId(mirror::Class* c)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (c == NULL) {
// c is the superclass of java.lang.Object or a primitive
@@ -577,7 +581,7 @@
}
std::pair<ClassSetIterator, bool> result = classes_.insert(c);
- const Class* present = *result.first;
+ const mirror::Class* present = *result.first;
// Make sure that we've assigned a string ID for this class' name
LookupClassNameId(c);
@@ -586,7 +590,7 @@
return (HprofStringId) present;
}
- HprofStringId LookupStringId(String* string) {
+ HprofStringId LookupStringId(mirror::String* string) {
return LookupStringId(string->ToModifiedUtf8());
}
@@ -604,7 +608,7 @@
return id;
}
- HprofStringId LookupClassNameId(const Class* c)
+ HprofStringId LookupClassNameId(const mirror::Class* c)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return LookupStringId(PrettyDescriptor(c));
}
@@ -740,7 +744,7 @@
// something when ctx->gc_scan_state_ is non-zero, which is usually
// only true when marking the root set or unreachable
// objects. Used to add rootset references to obj.
-int Hprof::MarkRootObject(const Object* obj, jobject jniObj) {
+int Hprof::MarkRootObject(const mirror::Object* obj, jobject jniObj) {
HprofRecord* rec = ¤t_record_;
HprofHeapTag heapTag = (HprofHeapTag)gc_scan_state_;
@@ -823,11 +827,11 @@
return 0;
}
-static int StackTraceSerialNumber(const Object* /*obj*/) {
+static int StackTraceSerialNumber(const mirror::Object* /*obj*/) {
return HPROF_NULL_STACK_TRACE;
}
-int Hprof::DumpHeapObject(Object* obj) {
+int Hprof::DumpHeapObject(mirror::Object* obj) {
HprofRecord* rec = ¤t_record_;
HprofHeapId desiredHeap = false ? HPROF_HEAP_ZYGOTE : HPROF_HEAP_APP; // TODO: zygote objects?
@@ -859,7 +863,7 @@
current_heap_ = desiredHeap;
}
- Class* c = obj->GetClass();
+ mirror::Class* c = obj->GetClass();
if (c == NULL) {
// This object will bother HprofReader, because it has a NULL
// class, so just don't dump it. It could be
@@ -867,7 +871,7 @@
// allocated which hasn't been initialized yet.
} else {
if (obj->IsClass()) {
- Class* thisClass = obj->AsClass();
+ mirror::Class* thisClass = obj->AsClass();
// obj is a ClassObject.
size_t sFieldCount = thisClass->NumStaticFields();
if (sFieldCount != 0) {
@@ -896,7 +900,7 @@
if (thisClass->IsClassClass()) {
// ClassObjects have their static fields appended, so aren't all the same size.
// But they're at least this size.
- rec->AddU4(sizeof(Class)); // instance size
+ rec->AddU4(sizeof(mirror::Class)); // instance size
} else if (thisClass->IsArrayClass() || thisClass->IsPrimitive()) {
rec->AddU4(0);
} else {
@@ -917,7 +921,7 @@
rec->AddId(CLASS_STATICS_ID(obj));
for (size_t i = 0; i < sFieldCount; ++i) {
- Field* f = thisClass->GetStaticField(i);
+ mirror::Field* f = thisClass->GetStaticField(i);
fh.ChangeField(f);
size_t size;
@@ -942,14 +946,14 @@
int iFieldCount = thisClass->IsObjectClass() ? 0 : thisClass->NumInstanceFields();
rec->AddU2((uint16_t)iFieldCount);
for (int i = 0; i < iFieldCount; ++i) {
- Field* f = thisClass->GetInstanceField(i);
+ mirror::Field* f = thisClass->GetInstanceField(i);
fh.ChangeField(f);
HprofBasicType t = SignatureToBasicTypeAndSize(fh.GetTypeDescriptor(), NULL);
rec->AddId(LookupStringId(fh.GetName()));
rec->AddU1(t);
}
} else if (c->IsArrayClass()) {
- const Array* aobj = obj->AsArray();
+ const mirror::Array* aobj = obj->AsArray();
uint32_t length = aobj->GetLength();
if (obj->IsObjectArray()) {
@@ -962,7 +966,7 @@
rec->AddId(LookupClassId(c));
// Dump the elements, which are always objects or NULL.
- rec->AddIdList((const HprofObjectId*)aobj->GetRawData(sizeof(Object*)), length);
+ rec->AddIdList((const HprofObjectId*)aobj->GetRawData(sizeof(mirror::Object*)), length);
} else {
size_t size;
HprofBasicType t = PrimitiveToBasicTypeAndSize(c->GetComponentType()->GetPrimitiveType(), &size);
@@ -1000,12 +1004,12 @@
// Write the instance data; fields for this class, followed by super class fields,
// and so on. Don't write the klass or monitor fields of Object.class.
- const Class* sclass = c;
+ const mirror::Class* sclass = c;
FieldHelper fh;
while (!sclass->IsObjectClass()) {
int ifieldCount = sclass->NumInstanceFields();
for (int i = 0; i < ifieldCount; ++i) {
- Field* f = sclass->GetInstanceField(i);
+ mirror::Field* f = sclass->GetInstanceField(i);
fh.ChangeField(f);
size_t size;
SignatureToBasicTypeAndSize(fh.GetTypeDescriptor(), &size);
@@ -1034,7 +1038,7 @@
return 0;
}
-void Hprof::VisitRoot(const Object* obj) {
+void Hprof::VisitRoot(const mirror::Object* obj) {
uint32_t threadId = 0; // TODO
/*RootType*/ size_t type = 0; // TODO
diff --git a/src/image.cc b/src/image.cc
index a190f10..8eeb772 100644
--- a/src/image.cc
+++ b/src/image.cc
@@ -16,9 +16,47 @@
#include "image.h"
+#include "mirror/object_array.h"
+#include "mirror/object_array-inl.h"
+#include "utils.h"
+
namespace art {
const byte ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' };
const byte ImageHeader::kImageVersion[] = { '0', '0', '2', '\0' };
+ImageHeader::ImageHeader(uint32_t image_begin,
+ uint32_t image_roots,
+ uint32_t oat_checksum,
+ uint32_t oat_file_begin,
+ uint32_t oat_data_begin,
+ uint32_t oat_data_end,
+ uint32_t oat_file_end)
+ : image_begin_(image_begin),
+ oat_checksum_(oat_checksum),
+ oat_file_begin_(oat_file_begin),
+ oat_data_begin_(oat_data_begin),
+ oat_data_end_(oat_data_end),
+ oat_file_end_(oat_file_end),
+ image_roots_(image_roots) {
+ CHECK_EQ(image_begin, RoundUp(image_begin, kPageSize));
+ CHECK_EQ(oat_file_begin, RoundUp(oat_file_begin, kPageSize));
+ CHECK_EQ(oat_data_begin, RoundUp(oat_data_begin, kPageSize));
+ CHECK_LT(image_begin, image_roots);
+ CHECK_LT(image_roots, oat_file_begin);
+ CHECK_LE(oat_file_begin, oat_data_begin);
+ CHECK_LT(oat_data_begin, oat_data_end);
+ CHECK_LE(oat_data_end, oat_file_end);
+ memcpy(magic_, kImageMagic, sizeof(kImageMagic));
+ memcpy(version_, kImageVersion, sizeof(kImageVersion));
+}
+
+mirror::Object* ImageHeader::GetImageRoot(ImageRoot image_root) const {
+ return GetImageRoots()->Get(image_root);
+}
+
+mirror::ObjectArray<mirror::Object>* ImageHeader::GetImageRoots() const {
+ return reinterpret_cast<mirror::ObjectArray<mirror::Object>*>(image_roots_);
+}
+
} // namespace art
diff --git a/src/image.h b/src/image.h
index f38f04b..6501328 100644
--- a/src/image.h
+++ b/src/image.h
@@ -20,7 +20,7 @@
#include <string.h>
#include "globals.h"
-#include "object.h"
+#include "mirror/object.h"
namespace art {
@@ -35,25 +35,7 @@
uint32_t oat_file_begin,
uint32_t oat_data_begin,
uint32_t oat_data_end,
- uint32_t oat_file_end)
- : image_begin_(image_begin),
- oat_checksum_(oat_checksum),
- oat_file_begin_(oat_file_begin),
- oat_data_begin_(oat_data_begin),
- oat_data_end_(oat_data_end),
- oat_file_end_(oat_file_end),
- image_roots_(image_roots) {
- CHECK_EQ(image_begin, RoundUp(image_begin, kPageSize));
- CHECK_EQ(oat_file_begin, RoundUp(oat_file_begin, kPageSize));
- CHECK_EQ(oat_data_begin, RoundUp(oat_data_begin, kPageSize));
- CHECK_LT(image_begin, image_roots);
- CHECK_LT(image_roots, oat_file_begin);
- CHECK_LE(oat_file_begin, oat_data_begin);
- CHECK_LT(oat_data_begin, oat_data_end);
- CHECK_LE(oat_data_end, oat_file_end);
- memcpy(magic_, kImageMagic, sizeof(kImageMagic));
- memcpy(version_, kImageVersion, sizeof(kImageVersion));
- }
+ uint32_t oat_file_end);
bool IsValid() const {
if (memcmp(magic_, kImageMagic, sizeof(kImageMagic) != 0)) {
@@ -113,15 +95,11 @@
kImageRootsMax,
};
- Object* GetImageRoot(ImageRoot image_root) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetImageRoots()->Get(image_root);
- }
+ mirror::Object* GetImageRoot(ImageRoot image_root) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
private:
- ObjectArray<Object>* GetImageRoots() const {
- return reinterpret_cast<ObjectArray<Object>*>(image_roots_);
- }
+ mirror::ObjectArray<mirror::Object>* GetImageRoots() const;
static const byte kImageMagic[4];
static const byte kImageVersion[4];
diff --git a/src/image_test.cc b/src/image_test.cc
index 89e3a05..ed6426b 100644
--- a/src/image_test.cc
+++ b/src/image_test.cc
@@ -54,7 +54,7 @@
for (size_t i = 0; i < java_lang_dex_file_->NumClassDefs(); ++i) {
const DexFile::ClassDef& class_def = java_lang_dex_file_->GetClassDef(i);
const char* descriptor = java_lang_dex_file_->GetClassDescriptor(class_def);
- Class* klass = class_linker_->FindSystemClass(descriptor);
+ mirror::Class* klass = class_linker_->FindSystemClass(descriptor);
EXPECT_TRUE(klass != NULL) << descriptor;
}
}
@@ -139,7 +139,7 @@
for (size_t i = 0; i < dex->NumClassDefs(); ++i) {
const DexFile::ClassDef& class_def = dex->GetClassDef(i);
const char* descriptor = dex->GetClassDescriptor(class_def);
- Class* klass = class_linker_->FindSystemClass(descriptor);
+ mirror::Class* klass = class_linker_->FindSystemClass(descriptor);
EXPECT_TRUE(klass != NULL) << descriptor;
EXPECT_LT(image_begin, reinterpret_cast<byte*>(klass)) << descriptor;
EXPECT_LT(reinterpret_cast<byte*>(klass), image_end) << descriptor;
diff --git a/src/image_writer.cc b/src/image_writer.cc
index fc88cbb..dc19d72 100644
--- a/src/image_writer.cc
+++ b/src/image_writer.cc
@@ -23,19 +23,25 @@
#include "base/logging.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
-#include "class_loader.h"
#include "compiled_method.h"
#include "compiler.h"
-#include "dex_cache.h"
+#include "gc/card_table-inl.h"
#include "gc/large_object_space.h"
#include "gc/space.h"
#include "globals.h"
#include "heap.h"
#include "image.h"
#include "intern_table.h"
+#include "mirror/array-inl.h"
+#include "mirror/class-inl.h"
+#include "mirror/class_loader.h"
+#include "mirror/dex_cache.h"
+#include "mirror/field-inl.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
#include "oat.h"
#include "oat_file.h"
-#include "object.h"
#include "object_utils.h"
#include "runtime.h"
#include "scoped_thread_state_change.h"
@@ -43,6 +49,8 @@
#include "UniquePtr.h"
#include "utils.h"
+using namespace art::mirror;
+
namespace art {
bool ImageWriter::Write(const std::string& image_filename,
@@ -442,7 +450,7 @@
DCHECK_LT(offset + n, image_writer->image_->Size());
memcpy(dst, src, n);
Object* copy = reinterpret_cast<Object*>(dst);
- copy->monitor_ = 0; // We may have inflated the lock during compilation.
+ copy->SetField32(Object::MonitorOffset(), 0, false); // We may have inflated the lock during compilation.
image_writer->FixupObject(obj, copy);
}
@@ -476,13 +484,13 @@
// Every type of method can have an invoke stub
uint32_t invoke_stub_offset = orig->GetOatInvokeStubOffset();
const byte* invoke_stub = GetOatAddress(invoke_stub_offset);
- copy->invoke_stub_ = reinterpret_cast<AbstractMethod::InvokeStub*>(const_cast<byte*>(invoke_stub));
+ copy->SetInvokeStub(reinterpret_cast<AbstractMethod::InvokeStub*>(const_cast<byte*>(invoke_stub)));
if (orig->IsAbstract()) {
// Abstract methods are pointed to a stub that will throw AbstractMethodError if they are called
ByteArray* orig_ame_stub_array_ = Runtime::Current()->GetAbstractMethodErrorStubArray();
ByteArray* copy_ame_stub_array_ = down_cast<ByteArray*>(GetImageAddress(orig_ame_stub_array_));
- copy->code_ = copy_ame_stub_array_->GetData();
+ copy->SetCode(copy_ame_stub_array_->GetData());
return;
}
@@ -492,7 +500,7 @@
Runtime::Current()->GetResolutionStubArray(Runtime::kUnknownMethod);
CHECK(orig->GetCode() == orig_res_stub_array_->GetData());
ByteArray* copy_res_stub_array_ = down_cast<ByteArray*>(GetImageAddress(orig_res_stub_array_));
- copy->code_ = copy_res_stub_array_->GetData();
+ copy->SetCode(copy_res_stub_array_->GetData());
return;
}
@@ -511,27 +519,27 @@
if (code == NULL) {
code = GetOatAddress(code_offset);
}
- copy->code_ = code;
+ copy->SetCode(code);
if (orig->IsNative()) {
// The native method's pointer is directed to a stub to lookup via dlsym.
// Note this is not the code_ pointer, that is handled above.
ByteArray* orig_jni_stub_array_ = Runtime::Current()->GetJniDlsymLookupStub();
ByteArray* copy_jni_stub_array_ = down_cast<ByteArray*>(GetImageAddress(orig_jni_stub_array_));
- copy->native_method_ = copy_jni_stub_array_->GetData();
+ copy->SetNativeMethod(copy_jni_stub_array_->GetData());
} else {
// normal (non-abstract non-native) methods have mapping tables to relocate
uint32_t mapping_table_off = orig->GetOatMappingTableOffset();
const byte* mapping_table = GetOatAddress(mapping_table_off);
- copy->mapping_table_ = reinterpret_cast<const uint32_t*>(mapping_table);
+ copy->SetMappingTable(reinterpret_cast<const uint32_t*>(mapping_table));
uint32_t vmap_table_offset = orig->GetOatVmapTableOffset();
const byte* vmap_table = GetOatAddress(vmap_table_offset);
- copy->vmap_table_ = reinterpret_cast<const uint16_t*>(vmap_table);
+ copy->SetVmapTable(reinterpret_cast<const uint16_t*>(vmap_table));
uint32_t native_gc_map_offset = orig->GetOatNativeGcMapOffset();
const byte* native_gc_map = GetOatAddress(native_gc_map_offset);
- copy->native_gc_map_ = reinterpret_cast<const uint8_t*>(native_gc_map);
+ copy->SetNativeGcMap(reinterpret_cast<const uint8_t*>(native_gc_map));
}
}
diff --git a/src/image_writer.h b/src/image_writer.h
index 64bac2e..eff9ffb 100644
--- a/src/image_writer.h
+++ b/src/image_writer.h
@@ -24,10 +24,9 @@
#include <string>
#include "compiler.h"
-#include "dex_cache.h"
#include "mem_map.h"
#include "oat_file.h"
-#include "object.h"
+#include "mirror/dex_cache.h"
#include "os.h"
#include "safe_map.h"
#include "gc/space.h"
@@ -59,7 +58,7 @@
bool AllocMemory();
// we use the lock word to store the offset of the object in the image
- void AssignImageOffset(Object* object)
+ void AssignImageOffset(mirror::Object* object)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(object != NULL);
SetImageOffset(object, image_end_);
@@ -67,35 +66,35 @@
DCHECK_LT(image_end_, image_->Size());
}
- void SetImageOffset(Object* object, size_t offset) {
+ void SetImageOffset(mirror::Object* object, size_t offset) {
DCHECK(object != NULL);
DCHECK_NE(offset, 0U);
DCHECK(!IsImageOffsetAssigned(object));
offsets_.Put(object, offset);
}
- size_t IsImageOffsetAssigned(const Object* object) const {
+ size_t IsImageOffsetAssigned(const mirror::Object* object) const {
DCHECK(object != NULL);
return offsets_.find(object) != offsets_.end();
}
- size_t GetImageOffset(const Object* object) const {
+ size_t GetImageOffset(const mirror::Object* object) const {
DCHECK(object != NULL);
DCHECK(IsImageOffsetAssigned(object));
return offsets_.find(object)->second;
}
- Object* GetImageAddress(const Object* object) const {
+ mirror::Object* GetImageAddress(const mirror::Object* object) const {
if (object == NULL) {
return NULL;
}
- return reinterpret_cast<Object*>(image_begin_ + GetImageOffset(object));
+ return reinterpret_cast<mirror::Object*>(image_begin_ + GetImageOffset(object));
}
- Object* GetLocalAddress(const Object* object) const {
+ mirror::Object* GetLocalAddress(const mirror::Object* object) const {
size_t offset = GetImageOffset(object);
byte* dst = image_->Begin() + offset;
- return reinterpret_cast<Object*>(dst);
+ return reinterpret_cast<mirror::Object*>(dst);
}
const byte* GetOatAddress(uint32_t offset) const {
@@ -106,50 +105,52 @@
return oat_data_begin_ + offset;
}
- bool IsImageClass(const Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool IsImageClass(const mirror::Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void DumpImageClasses();
void ComputeLazyFieldsForImageClasses()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static bool ComputeLazyFieldsForClassesVisitor(Class* klass, void* arg)
+ static bool ComputeLazyFieldsForClassesVisitor(mirror::Class* klass, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Wire dex cache resolved strings to strings in the image to avoid runtime resolution
void ComputeEagerResolvedStrings();
- static void ComputeEagerResolvedStringsCallback(Object* obj, void* arg)
+ static void ComputeEagerResolvedStringsCallback(mirror::Object* obj, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void PruneNonImageClasses() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static bool NonImageClassesVisitor(Class* c, void* arg)
+ static bool NonImageClassesVisitor(mirror::Class* c, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void CheckNonImageClassesRemoved();
- static void CheckNonImageClassesRemovedCallback(Object* obj, void* arg)
+ static void CheckNonImageClassesRemovedCallback(mirror::Object* obj, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void CalculateNewObjectOffsets(size_t oat_loaded_size, size_t oat_data_offset)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ObjectArray<Object>* CreateImageRoots() const
+ mirror::ObjectArray<mirror::Object>* CreateImageRoots() const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static void CalculateNewObjectOffsetsCallback(Object* obj, void* arg)
+ static void CalculateNewObjectOffsetsCallback(mirror::Object* obj, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void CopyAndFixupObjects();
- static void CopyAndFixupObjectsCallback(Object* obj, void* arg)
+ static void CopyAndFixupObjectsCallback(mirror::Object* obj, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupClass(const Class* orig, Class* copy)
+ void FixupClass(const mirror::Class* orig, mirror::Class* copy)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupMethod(const AbstractMethod* orig, AbstractMethod* copy)
+ void FixupMethod(const mirror::AbstractMethod* orig, mirror::AbstractMethod* copy)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupObject(const Object* orig, Object* copy)
+ void FixupObject(const mirror::Object* orig, mirror::Object* copy)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupObjectArray(const ObjectArray<Object>* orig, ObjectArray<Object>* copy)
+ void FixupObjectArray(const mirror::ObjectArray<mirror::Object>* orig,
+ mirror::ObjectArray<mirror::Object>* copy)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupInstanceFields(const Object* orig, Object* copy)
+ void FixupInstanceFields(const mirror::Object* orig, mirror::Object* copy)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupStaticFields(const Class* orig, Class* copy)
+ void FixupStaticFields(const mirror::Class* orig, mirror::Class* copy)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void FixupFields(const Object* orig, Object* copy, uint32_t ref_offsets, bool is_static)
+ void FixupFields(const mirror::Object* orig, mirror::Object* copy, uint32_t ref_offsets,
+ bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void PatchOatCodeAndMethods(const Compiler& compiler)
@@ -157,7 +158,7 @@
void SetPatchLocation(const Compiler::PatchInformation* patch, uint32_t value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- SafeMap<const Object*, size_t> offsets_;
+ SafeMap<const mirror::Object*, size_t> offsets_;
// oat file with code for this image
OatFile* oat_file_;
@@ -178,7 +179,7 @@
const byte* oat_data_begin_;
// DexCaches seen while scanning for fixing up CodeAndDirectMethods
- typedef std::set<DexCache*> Set;
+ typedef std::set<mirror::DexCache*> Set;
Set dex_caches_;
};
diff --git a/src/indirect_reference_table.cc b/src/indirect_reference_table.cc
index 9bb6edc..720380a 100644
--- a/src/indirect_reference_table.cc
+++ b/src/indirect_reference_table.cc
@@ -40,9 +40,9 @@
CHECK_LE(initialCount, maxCount);
CHECK_NE(desiredKind, kSirtOrInvalid);
- table_ = reinterpret_cast<const Object**>(malloc(initialCount * sizeof(const Object*)));
+ table_ = reinterpret_cast<const mirror::Object**>(malloc(initialCount * sizeof(const mirror::Object*)));
CHECK(table_ != NULL);
- memset(table_, 0xd1, initialCount * sizeof(const Object*));
+ memset(table_, 0xd1, initialCount * sizeof(const mirror::Object*));
slot_data_ = reinterpret_cast<IndirectRefSlot*>(calloc(initialCount, sizeof(IndirectRefSlot)));
CHECK(slot_data_ != NULL);
@@ -63,7 +63,7 @@
// Make sure that the entry at "idx" is correctly paired with "iref".
bool IndirectReferenceTable::CheckEntry(const char* what, IndirectRef iref, int idx) const {
- const Object* obj = table_[idx];
+ const mirror::Object* obj = table_[idx];
IndirectRef checkRef = ToIndirectRef(obj, idx);
if (checkRef != iref) {
LOG(ERROR) << "JNI ERROR (app bug): attempt to " << what
@@ -75,7 +75,7 @@
return true;
}
-IndirectRef IndirectReferenceTable::Add(uint32_t cookie, const Object* obj) {
+IndirectRef IndirectReferenceTable::Add(uint32_t cookie, const mirror::Object* obj) {
IRTSegmentState prevState;
prevState.all = cookie;
size_t topIndex = segment_state_.parts.topIndex;
@@ -101,7 +101,7 @@
}
DCHECK_GT(newSize, alloc_entries_);
- table_ = reinterpret_cast<const Object**>(realloc(table_, newSize * sizeof(const Object*)));
+ table_ = reinterpret_cast<const mirror::Object**>(realloc(table_, newSize * sizeof(const mirror::Object*)));
slot_data_ = reinterpret_cast<IndirectRefSlot*>(realloc(slot_data_,
newSize * sizeof(IndirectRefSlot)));
if (table_ == NULL || slot_data_ == NULL) {
@@ -126,7 +126,7 @@
if (numHoles > 0) {
DCHECK_GT(topIndex, 1U);
// Find the first hole; likely to be near the end of the list.
- const Object** pScan = &table_[topIndex - 1];
+ const mirror::Object** pScan = &table_[topIndex - 1];
DCHECK(*pScan != NULL);
while (*--pScan != NULL) {
DCHECK_GE(pScan, table_ + prevState.parts.topIndex);
@@ -194,7 +194,7 @@
return true;
}
-static int Find(Object* direct_pointer, int bottomIndex, int topIndex, const Object** table) {
+static int Find(mirror::Object* direct_pointer, int bottomIndex, int topIndex, const mirror::Object** table) {
for (int i = bottomIndex; i < topIndex; ++i) {
if (table[i] == direct_pointer) {
return i;
@@ -203,7 +203,7 @@
return -1;
}
-bool IndirectReferenceTable::ContainsDirectPointer(Object* direct_pointer) const {
+bool IndirectReferenceTable::ContainsDirectPointer(mirror::Object* direct_pointer) const {
return Find(direct_pointer, 0, segment_state_.parts.topIndex, table_) != -1;
}
@@ -234,7 +234,7 @@
return true;
}
if (GetIndirectRefKind(iref) == kSirtOrInvalid && vm->work_around_app_jni_bugs) {
- Object* direct_pointer = reinterpret_cast<Object*>(iref);
+ mirror::Object* direct_pointer = reinterpret_cast<mirror::Object*>(iref);
idx = Find(direct_pointer, bottomIndex, topIndex, table_);
if (idx == -1) {
LOG(WARNING) << "trying to work around app JNI bugs, but didn't find " << iref << " in table!";
@@ -308,7 +308,7 @@
return true;
}
-void IndirectReferenceTable::VisitRoots(Heap::RootVisitor* visitor, void* arg) {
+void IndirectReferenceTable::VisitRoots(RootVisitor* visitor, void* arg) {
typedef IndirectReferenceTable::iterator It; // TODO: C++0x auto
for (It it = begin(), end = this->end(); it != end; ++it) {
visitor(**it, arg);
@@ -317,7 +317,7 @@
void IndirectReferenceTable::Dump(std::ostream& os) const {
os << kind_ << " table dump:\n";
- std::vector<const Object*> entries(table_, table_ + Capacity());
+ std::vector<const mirror::Object*> entries(table_, table_ + Capacity());
// Remove NULLs.
for (int i = entries.size() - 1; i >= 0; --i) {
if (entries[i] == NULL) {
diff --git a/src/indirect_reference_table.h b/src/indirect_reference_table.h
index cd358e9..e09043d 100644
--- a/src/indirect_reference_table.h
+++ b/src/indirect_reference_table.h
@@ -23,11 +23,13 @@
#include <string>
#include "base/logging.h"
-#include "heap.h"
+#include "offsets.h"
+#include "root_visitor.h"
namespace art {
-
+namespace mirror {
class Object;
+} // namespace mirror
/*
* Maintain a table of indirect references. Used for local/global JNI
@@ -98,8 +100,8 @@
typedef void* IndirectRef;
// Magic failure values; must not pass Heap::ValidateObject() or Heap::IsHeapAddress().
-static Object* const kInvalidIndirectRefObject = reinterpret_cast<Object*>(0xdead4321);
-static Object* const kClearedJniWeakGlobal = reinterpret_cast<Object*>(0xdead1234);
+static mirror::Object* const kInvalidIndirectRefObject = reinterpret_cast<mirror::Object*>(0xdead4321);
+static mirror::Object* const kClearedJniWeakGlobal = reinterpret_cast<mirror::Object*>(0xdead1234);
/*
* Indirect reference kind, used as the two low bits of IndirectRef.
@@ -128,7 +130,7 @@
static const size_t kIRTPrevCount = 4;
struct IndirectRefSlot {
uint32_t serial;
- const Object* previous[kIRTPrevCount];
+ const mirror::Object* previous[kIRTPrevCount];
};
/* use as initial value for "cookie", and when table has only one segment */
@@ -204,7 +206,7 @@
class IrtIterator {
public:
- explicit IrtIterator(const Object** table, size_t i, size_t capacity)
+ explicit IrtIterator(const mirror::Object** table, size_t i, size_t capacity)
: table_(table), i_(i), capacity_(capacity) {
SkipNullsAndTombstones();
}
@@ -215,7 +217,7 @@
return *this;
}
- const Object** operator*() {
+ const mirror::Object** operator*() {
return &table_[i_];
}
@@ -231,7 +233,7 @@
}
}
- const Object** table_;
+ const mirror::Object** table_;
size_t i_;
size_t capacity_;
};
@@ -258,7 +260,7 @@
* Returns NULL if the table is full (max entries reached, or alloc
* failed during expansion).
*/
- IndirectRef Add(uint32_t cookie, const Object* obj)
+ IndirectRef Add(uint32_t cookie, const mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
/*
@@ -266,7 +268,7 @@
*
* Returns kInvalidIndirectRefObject if iref is invalid.
*/
- const Object* Get(IndirectRef iref) const {
+ const mirror::Object* Get(IndirectRef iref) const {
if (!GetChecked(iref)) {
return kInvalidIndirectRefObject;
}
@@ -274,7 +276,7 @@
}
// TODO: remove when we remove work_around_app_jni_bugs support.
- bool ContainsDirectPointer(Object* direct_pointer) const;
+ bool ContainsDirectPointer(mirror::Object* direct_pointer) const;
/*
* Remove an existing entry.
@@ -307,7 +309,7 @@
return iterator(table_, Capacity(), Capacity());
}
- void VisitRoots(Heap::RootVisitor* visitor, void* arg);
+ void VisitRoots(RootVisitor* visitor, void* arg);
uint32_t GetSegmentState() const {
return segment_state_.all;
@@ -334,7 +336,7 @@
* The object pointer itself is subject to relocation in some GC
* implementations, so we shouldn't really be using it here.
*/
- IndirectRef ToIndirectRef(const Object* /*o*/, uint32_t tableIndex) const {
+ IndirectRef ToIndirectRef(const mirror::Object* /*o*/, uint32_t tableIndex) const {
DCHECK_LT(tableIndex, 65536U);
uint32_t serialChunk = slot_data_[tableIndex].serial;
uint32_t uref = serialChunk << 20 | (tableIndex << 2) | kind_;
@@ -347,7 +349,7 @@
* We advance the serial number, invalidating any outstanding references to
* this slot.
*/
- void UpdateSlotAdd(const Object* obj, int slot) {
+ void UpdateSlotAdd(const mirror::Object* obj, int slot) {
if (slot_data_ != NULL) {
IndirectRefSlot* pSlot = &slot_data_[slot];
pSlot->serial++;
@@ -363,7 +365,7 @@
IRTSegmentState segment_state_;
/* bottom of the stack */
- const Object** table_;
+ const mirror::Object** table_;
/* bit mask, ORed into all irefs */
IndirectRefKind kind_;
/* extended debugging info */
diff --git a/src/indirect_reference_table_test.cc b/src/indirect_reference_table_test.cc
index b5a05ec..bd2890c 100644
--- a/src/indirect_reference_table_test.cc
+++ b/src/indirect_reference_table_test.cc
@@ -47,15 +47,15 @@
static const size_t kTableMax = 20;
IndirectReferenceTable irt(kTableInitial, kTableMax, kGlobal);
- Class* c = class_linker_->FindSystemClass("Ljava/lang/Object;");
+ mirror::Class* c = class_linker_->FindSystemClass("Ljava/lang/Object;");
ASSERT_TRUE(c != NULL);
- Object* obj0 = c->AllocObject(soa.Self());
+ mirror::Object* obj0 = c->AllocObject(soa.Self());
ASSERT_TRUE(obj0 != NULL);
- Object* obj1 = c->AllocObject(soa.Self());
+ mirror::Object* obj1 = c->AllocObject(soa.Self());
ASSERT_TRUE(obj1 != NULL);
- Object* obj2 = c->AllocObject(soa.Self());
+ mirror::Object* obj2 = c->AllocObject(soa.Self());
ASSERT_TRUE(obj2 != NULL);
- Object* obj3 = c->AllocObject(soa.Self());
+ mirror::Object* obj3 = c->AllocObject(soa.Self());
ASSERT_TRUE(obj3 != NULL);
const uint32_t cookie = IRT_FIRST_SEGMENT;
diff --git a/src/instrumentation.cc b/src/instrumentation.cc
index 065758d..e3d4d28 100644
--- a/src/instrumentation.cc
+++ b/src/instrumentation.cc
@@ -21,7 +21,10 @@
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
#include "debugger.h"
-#include "dex_cache.h"
+#include "mirror/class-inl.h"
+#include "mirror/dex_cache.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object_array-inl.h"
#if !defined(ART_USE_LLVM_COMPILER)
#include "oat/runtime/oat_support_entrypoints.h"
#endif
@@ -34,18 +37,18 @@
namespace art {
-static bool InstallStubsClassVisitor(Class* klass, void*)
+static bool InstallStubsClassVisitor(mirror::Class* klass, void*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
- AbstractMethod* method = klass->GetDirectMethod(i);
+ mirror::AbstractMethod* method = klass->GetDirectMethod(i);
if (instrumentation->GetSavedCodeFromMap(method) == NULL) {
instrumentation->SaveAndUpdateCode(method);
}
}
for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
- AbstractMethod* method = klass->GetVirtualMethod(i);
+ mirror::AbstractMethod* method = klass->GetVirtualMethod(i);
if (instrumentation->GetSavedCodeFromMap(method) == NULL) {
instrumentation->SaveAndUpdateCode(method);
}
@@ -53,18 +56,18 @@
return true;
}
-static bool UninstallStubsClassVisitor(Class* klass, void*)
+static bool UninstallStubsClassVisitor(mirror::Class* klass, void*)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
- AbstractMethod* method = klass->GetDirectMethod(i);
+ mirror::AbstractMethod* method = klass->GetDirectMethod(i);
if (instrumentation->GetSavedCodeFromMap(method) != NULL) {
instrumentation->ResetSavedCode(method);
}
}
for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
- AbstractMethod* method = klass->GetVirtualMethod(i);
+ mirror::AbstractMethod* method = klass->GetVirtualMethod(i);
if (instrumentation->GetSavedCodeFromMap(method) != NULL) {
instrumentation->ResetSavedCode(method);
}
@@ -83,7 +86,7 @@
if (GetCurrentQuickFrame() == NULL) {
return true; // Ignore shadow frames.
}
- AbstractMethod* m = GetMethod();
+ mirror::AbstractMethod* m = GetMethod();
if (m == NULL) {
return true; // Ignore upcalls.
}
@@ -125,7 +128,7 @@
if (self_->IsInstrumentationStackEmpty()) {
return false; // Stop.
}
- AbstractMethod* m = GetMethod();
+ mirror::AbstractMethod* m = GetMethod();
if (m == NULL) {
return true; // Ignore upcalls.
}
@@ -171,16 +174,16 @@
Runtime::Current()->GetThreadList()->ForEach(InstrumentationRestoreStack, NULL);
}
-void Instrumentation::AddSavedCodeToMap(const AbstractMethod* method, const void* code) {
+void Instrumentation::AddSavedCodeToMap(const mirror::AbstractMethod* method, const void* code) {
saved_code_map_.Put(method, code);
}
-void Instrumentation::RemoveSavedCodeFromMap(const AbstractMethod* method) {
+void Instrumentation::RemoveSavedCodeFromMap(const mirror::AbstractMethod* method) {
saved_code_map_.erase(method);
}
-const void* Instrumentation::GetSavedCodeFromMap(const AbstractMethod* method) {
- typedef SafeMap<const AbstractMethod*, const void*>::const_iterator It; // TODO: C++0x auto
+const void* Instrumentation::GetSavedCodeFromMap(const mirror::AbstractMethod* method) {
+ typedef SafeMap<const mirror::AbstractMethod*, const void*>::const_iterator It; // TODO: C++0x auto
It it = saved_code_map_.find(method);
if (it == saved_code_map_.end()) {
return NULL;
@@ -189,7 +192,7 @@
}
}
-void Instrumentation::SaveAndUpdateCode(AbstractMethod* method) {
+void Instrumentation::SaveAndUpdateCode(mirror::AbstractMethod* method) {
#if defined(ART_USE_LLVM_COMPILER)
UNUSED(method);
UNIMPLEMENTED(FATAL);
@@ -201,7 +204,7 @@
#endif
}
-void Instrumentation::ResetSavedCode(AbstractMethod* method) {
+void Instrumentation::ResetSavedCode(mirror::AbstractMethod* method) {
CHECK(GetSavedCodeFromMap(method) != NULL);
method->SetCode(GetSavedCodeFromMap(method));
RemoveSavedCodeFromMap(method);
@@ -223,7 +226,7 @@
uint32_t InstrumentationMethodUnwindFromCode(Thread* self) {
Trace* trace = Runtime::Current()->GetInstrumentation()->GetTrace();
InstrumentationStackFrame instrumentation_frame = self->PopInstrumentationStackFrame();
- AbstractMethod* method = instrumentation_frame.method_;
+ mirror::AbstractMethod* method = instrumentation_frame.method_;
uint32_t lr = instrumentation_frame.return_pc_;
trace->LogMethodTraceEvent(self, method, Trace::kMethodTraceUnwind);
diff --git a/src/instrumentation.h b/src/instrumentation.h
index 00060ce..fb49bf8 100644
--- a/src/instrumentation.h
+++ b/src/instrumentation.h
@@ -17,29 +17,27 @@
#ifndef ART_SRC_INSTRUMENTATION_H_
#define ART_SRC_INSTRUMENTATION_H_
-#include <ostream>
-#include <set>
-#include <string>
-
#include "base/macros.h"
-#include "globals.h"
#include "safe_map.h"
-#include "trace.h"
-#include "UniquePtr.h"
+
+#include <stdint.h>
namespace art {
+namespace mirror {
class AbstractMethod;
+}
class Thread;
+class Trace;
uint32_t InstrumentationMethodUnwindFromCode(Thread* self);
struct InstrumentationStackFrame {
InstrumentationStackFrame() : method_(NULL), return_pc_(0), frame_id_(0) {}
- InstrumentationStackFrame(AbstractMethod* method, uintptr_t return_pc, size_t frame_id)
+ InstrumentationStackFrame(mirror::AbstractMethod* method, uintptr_t return_pc, size_t frame_id)
: method_(method), return_pc_(return_pc), frame_id_(frame_id) {
}
- AbstractMethod* method_;
+ mirror::AbstractMethod* method_;
uintptr_t return_pc_;
size_t frame_id_;
};
@@ -55,20 +53,20 @@
// Restores original code for each method and fixes the return values of each thread's stack.
void UninstallStubs() LOCKS_EXCLUDED(Locks::thread_list_lock_);
- const void* GetSavedCodeFromMap(const AbstractMethod* method);
- void SaveAndUpdateCode(AbstractMethod* method);
- void ResetSavedCode(AbstractMethod* method);
+ const void* GetSavedCodeFromMap(const mirror::AbstractMethod* method);
+ void SaveAndUpdateCode(mirror::AbstractMethod* method);
+ void ResetSavedCode(mirror::AbstractMethod* method);
Trace* GetTrace() const;
void SetTrace(Trace* trace);
void RemoveTrace();
private:
- void AddSavedCodeToMap(const AbstractMethod* method, const void* code);
- void RemoveSavedCodeFromMap(const AbstractMethod* method);
+ void AddSavedCodeToMap(const mirror::AbstractMethod* method, const void* code);
+ void RemoveSavedCodeFromMap(const mirror::AbstractMethod* method);
// Maps a method to its original code pointer.
- SafeMap<const AbstractMethod*, const void*> saved_code_map_;
+ SafeMap<const mirror::AbstractMethod*, const void*> saved_code_map_;
Trace* trace_;
diff --git a/src/intern_table.cc b/src/intern_table.cc
index 817ce1e..fa3c075 100644
--- a/src/intern_table.cc
+++ b/src/intern_table.cc
@@ -16,6 +16,8 @@
#include "intern_table.h"
+#include "mirror/string.h"
+#include "thread.h"
#include "UniquePtr.h"
#include "utf.h"
@@ -36,7 +38,7 @@
<< image_strong_interns_.size() << " image strong\n";
}
-void InternTable::VisitRoots(Heap::RootVisitor* visitor, void* arg) {
+void InternTable::VisitRoots(RootVisitor* visitor, void* arg) {
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) {
@@ -46,11 +48,11 @@
// Note: we deliberately don't visit the weak_interns_ table and the immutable image roots.
}
-String* InternTable::Lookup(Table& table, String* s, uint32_t hash_code) {
+mirror::String* InternTable::Lookup(Table& table, mirror::String* s, uint32_t hash_code) {
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;
+ mirror::String* existing_string = it->second;
if (existing_string->Equals(s)) {
return existing_string;
}
@@ -58,18 +60,18 @@
return NULL;
}
-String* InternTable::Insert(Table& table, String* s, uint32_t hash_code) {
+mirror::String* InternTable::Insert(Table& table, mirror::String* s, uint32_t hash_code) {
intern_table_lock_.AssertHeld(Thread::Current());
table.insert(std::make_pair(hash_code, s));
return s;
}
-void InternTable::RegisterStrong(String* s) {
+void InternTable::RegisterStrong(mirror::String* s) {
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) {
+void InternTable::Remove(Table& table, const mirror::String* s, uint32_t hash_code) {
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) {
@@ -80,7 +82,7 @@
}
}
-String* InternTable::Insert(String* s, bool is_strong) {
+mirror::String* InternTable::Insert(mirror::String* s, bool is_strong) {
MutexLock mu(Thread::Current(), intern_table_lock_);
DCHECK(s != NULL);
@@ -88,12 +90,12 @@
if (is_strong) {
// Check the strong table for a match.
- String* strong = Lookup(strong_interns_, s, hash_code);
+ mirror::String* strong = Lookup(strong_interns_, s, hash_code);
if (strong != NULL) {
return strong;
}
// Check the image table for a match.
- String* image = Lookup(image_strong_interns_, s, hash_code);
+ mirror::String* image = Lookup(image_strong_interns_, s, hash_code);
if (image != NULL) {
return image;
}
@@ -102,7 +104,7 @@
Dirty();
// There is no match in the strong table, check the weak table.
- String* weak = Lookup(weak_interns_, s, hash_code);
+ mirror::String* weak = Lookup(weak_interns_, s, hash_code);
if (weak != NULL) {
// A match was found in the weak table. Promote to the strong table.
Remove(weak_interns_, weak, hash_code);
@@ -114,17 +116,17 @@
}
// Check the strong table for a match.
- String* strong = Lookup(strong_interns_, s, hash_code);
+ mirror::String* strong = Lookup(strong_interns_, s, hash_code);
if (strong != NULL) {
return strong;
}
// Check the image table for a match.
- String* image = Lookup(image_strong_interns_, s, hash_code);
+ mirror::String* image = Lookup(image_strong_interns_, s, hash_code);
if (image != NULL) {
return image;
}
// Check the weak table for a match.
- String* weak = Lookup(weak_interns_, s, hash_code);
+ mirror::String* weak = Lookup(weak_interns_, s, hash_code);
if (weak != NULL) {
return weak;
}
@@ -132,39 +134,39 @@
return Insert(weak_interns_, s, hash_code);
}
-String* InternTable::InternStrong(int32_t utf16_length, const char* utf8_data) {
- return InternStrong(String::AllocFromModifiedUtf8(Thread::Current(), utf16_length, utf8_data));
+mirror::String* InternTable::InternStrong(int32_t utf16_length, const char* utf8_data) {
+ return InternStrong(mirror::String::AllocFromModifiedUtf8(Thread::Current(), utf16_length, utf8_data));
}
-String* InternTable::InternStrong(const char* utf8_data) {
- return InternStrong(String::AllocFromModifiedUtf8(Thread::Current(), utf8_data));
+mirror::String* InternTable::InternStrong(const char* utf8_data) {
+ return InternStrong(mirror::String::AllocFromModifiedUtf8(Thread::Current(), utf8_data));
}
-String* InternTable::InternStrong(String* s) {
+mirror::String* InternTable::InternStrong(mirror::String* s) {
if (s == NULL) {
return NULL;
}
return Insert(s, true);
}
-String* InternTable::InternWeak(String* s) {
+mirror::String* InternTable::InternWeak(mirror::String* s) {
if (s == NULL) {
return NULL;
}
return Insert(s, false);
}
-bool InternTable::ContainsWeak(String* s) {
+bool InternTable::ContainsWeak(mirror::String* s) {
MutexLock mu(Thread::Current(), intern_table_lock_);
- const String* found = Lookup(weak_interns_, s, s->GetHashCode());
+ const mirror::String* found = Lookup(weak_interns_, s, s->GetHashCode());
return found == s;
}
-void InternTable::SweepInternTableWeaks(Heap::IsMarkedTester is_marked, void* arg) {
+void InternTable::SweepInternTableWeaks(IsMarkedTester is_marked, void* arg) {
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;
+ mirror::Object* object = it->second;
if (!is_marked(object, arg)) {
weak_interns_.erase(it++);
} else {
diff --git a/src/intern_table.h b/src/intern_table.h
index 06a2b89..3018317 100644
--- a/src/intern_table.h
+++ b/src/intern_table.h
@@ -17,14 +17,15 @@
#ifndef ART_SRC_INTERN_TABLE_H_
#define ART_SRC_INTERN_TABLE_H_
-#include <iosfwd>
-
#include "base/mutex.h"
-#include "heap.h"
-#include "object.h"
-#include "safe_map.h"
+#include "root_visitor.h"
+
+#include <map>
namespace art {
+namespace mirror {
+class String;
+} // namespace mirror
/**
* Used to intern strings.
@@ -41,31 +42,31 @@
InternTable();
// Interns a potentially new string in the 'strong' table. (See above.)
- String* InternStrong(int32_t utf16_length, const char* utf8_data)
+ mirror::String* InternStrong(int32_t utf16_length, const char* utf8_data)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Interns a potentially new string in the 'strong' table. (See above.)
- String* InternStrong(const char* utf8_data)
+ mirror::String* InternStrong(const char* utf8_data)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Interns a potentially new string in the 'strong' table. (See above.)
- String* InternStrong(String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::String* InternStrong(mirror::String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Interns a potentially new string in the 'weak' table. (See above.)
- String* InternWeak(String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::String* InternWeak(mirror::String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Register a String trusting that it is safe to intern.
// Used when reinitializing InternTable from an image.
- void RegisterStrong(String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void RegisterStrong(mirror::String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SweepInternTableWeaks(Heap::IsMarkedTester is_marked, void* arg)
+ void SweepInternTableWeaks(IsMarkedTester is_marked, void* arg)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
- bool ContainsWeak(String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool ContainsWeak(mirror::String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
size_t Size() const;
- void VisitRoots(Heap::RootVisitor* visitor, void* arg);
+ void VisitRoots(RootVisitor* visitor, void* arg);
void DumpForSigQuit(std::ostream& os) const;
@@ -75,15 +76,15 @@
}
private:
- typedef std::multimap<int32_t, String*> Table;
+ typedef std::multimap<int32_t, mirror::String*> Table;
- String* Insert(String* s, bool is_strong)
+ mirror::String* Insert(mirror::String* s, bool is_strong)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- String* Lookup(Table& table, String* s, uint32_t hash_code)
+ mirror::String* Lookup(Table& table, mirror::String* s, uint32_t hash_code)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- String* Insert(Table& table, String* s, uint32_t hash_code);
- void Remove(Table& table, const String* s, uint32_t hash_code);
+ mirror::String* Insert(Table& table, mirror::String* s, uint32_t hash_code);
+ void Remove(Table& table, const mirror::String* s, uint32_t hash_code);
mutable Mutex intern_table_lock_;
bool is_dirty_;
diff --git a/src/intern_table_test.cc b/src/intern_table_test.cc
index ee9165e..f6b040d 100644
--- a/src/intern_table_test.cc
+++ b/src/intern_table_test.cc
@@ -17,7 +17,7 @@
#include "intern_table.h"
#include "common_test.h"
-#include "object.h"
+#include "mirror/object.h"
#include "sirt_ref.h"
namespace art {
@@ -27,10 +27,10 @@
TEST_F(InternTableTest, Intern) {
ScopedObjectAccess soa(Thread::Current());
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(soa.Self(), "foo"));
- SirtRef<String> bar(soa.Self(), intern_table.InternStrong(3, "bar"));
+ SirtRef<mirror::String> foo_1(soa.Self(), intern_table.InternStrong(3, "foo"));
+ SirtRef<mirror::String> foo_2(soa.Self(), intern_table.InternStrong(3, "foo"));
+ SirtRef<mirror::String> foo_3(soa.Self(), mirror::String::AllocFromModifiedUtf8(soa.Self(), "foo"));
+ SirtRef<mirror::String> bar(soa.Self(), intern_table.InternStrong(3, "bar"));
EXPECT_TRUE(foo_1->Equals("foo"));
EXPECT_TRUE(foo_2->Equals("foo"));
EXPECT_TRUE(foo_3->Equals("foo"));
@@ -47,7 +47,7 @@
InternTable t;
EXPECT_EQ(0U, t.Size());
t.InternStrong(3, "foo");
- SirtRef<String> foo(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "foo"));
+ SirtRef<mirror::String> foo(soa.Self(), mirror::String::AllocFromModifiedUtf8(soa.Self(), "foo"));
t.InternWeak(foo.get());
EXPECT_EQ(1U, t.Size());
t.InternStrong(3, "bar");
@@ -56,9 +56,9 @@
class TestPredicate {
public:
- bool IsMarked(const Object* s) const {
+ bool IsMarked(const mirror::Object* s) const {
bool erased = false;
- typedef std::vector<const String*>::iterator It; // TODO: C++0x auto
+ typedef std::vector<const mirror::String*>::iterator It; // TODO: C++0x auto
for (It it = expected_.begin(), end = expected_.end(); it != end; ++it) {
if (*it == s) {
expected_.erase(it);
@@ -70,7 +70,7 @@
return false;
}
- void Expect(const String* s) {
+ void Expect(const mirror::String* s) {
expected_.push_back(s);
}
@@ -79,10 +79,10 @@
}
private:
- mutable std::vector<const String*> expected_;
+ mutable std::vector<const mirror::String*> expected_;
};
-bool IsMarked(const Object* object, void* arg) {
+bool IsMarked(const mirror::Object* object, void* arg) {
return reinterpret_cast<TestPredicate*>(arg)->IsMarked(object);
}
@@ -91,10 +91,12 @@
InternTable t;
t.InternStrong(3, "foo");
t.InternStrong(3, "bar");
- 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()));
+ SirtRef<mirror::String> hello(soa.Self(),
+ mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello"));
+ SirtRef<mirror::String> world(soa.Self(),
+ mirror::String::AllocFromModifiedUtf8(soa.Self(), "world"));
+ SirtRef<mirror::String> s0(soa.Self(), t.InternWeak(hello.get()));
+ SirtRef<mirror::String> s1(soa.Self(), t.InternWeak(world.get()));
EXPECT_EQ(4U, t.Size());
@@ -110,7 +112,8 @@
EXPECT_EQ(2U, t.Size());
// Just check that we didn't corrupt the map.
- SirtRef<String> still_here(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "still here"));
+ SirtRef<mirror::String> still_here(soa.Self(),
+ mirror::String::AllocFromModifiedUtf8(soa.Self(), "still here"));
t.InternWeak(still_here.get());
EXPECT_EQ(3U, t.Size());
}
@@ -120,9 +123,9 @@
{
// Strongs are never weak.
InternTable t;
- SirtRef<String> interned_foo_1(soa.Self(), t.InternStrong(3, "foo"));
+ SirtRef<mirror::String> interned_foo_1(soa.Self(), t.InternStrong(3, "foo"));
EXPECT_FALSE(t.ContainsWeak(interned_foo_1.get()));
- SirtRef<String> interned_foo_2(soa.Self(), t.InternStrong(3, "foo"));
+ SirtRef<mirror::String> interned_foo_2(soa.Self(), t.InternStrong(3, "foo"));
EXPECT_FALSE(t.ContainsWeak(interned_foo_2.get()));
EXPECT_EQ(interned_foo_1.get(), interned_foo_2.get());
}
@@ -130,11 +133,13 @@
{
// Weaks are always weak.
InternTable t;
- SirtRef<String> foo_1(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "foo"));
- SirtRef<String> foo_2(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "foo"));
+ SirtRef<mirror::String> foo_1(soa.Self(),
+ mirror::String::AllocFromModifiedUtf8(soa.Self(), "foo"));
+ SirtRef<mirror::String> foo_2(soa.Self(),
+ mirror::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()));
+ SirtRef<mirror::String> interned_foo_1(soa.Self(), t.InternWeak(foo_1.get()));
+ SirtRef<mirror::String> interned_foo_2(soa.Self(), t.InternWeak(foo_2.get()));
EXPECT_TRUE(t.ContainsWeak(interned_foo_2.get()));
EXPECT_EQ(interned_foo_1.get(), interned_foo_2.get());
}
@@ -142,10 +147,10 @@
{
// A weak can be promoted to a strong.
InternTable t;
- SirtRef<String> foo(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), "foo"));
- SirtRef<String> interned_foo_1(soa.Self(), t.InternWeak(foo.get()));
+ SirtRef<mirror::String> foo(soa.Self(), mirror::String::AllocFromModifiedUtf8(soa.Self(), "foo"));
+ SirtRef<mirror::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"));
+ SirtRef<mirror::String> interned_foo_2(soa.Self(), t.InternStrong(3, "foo"));
EXPECT_FALSE(t.ContainsWeak(interned_foo_2.get()));
EXPECT_EQ(interned_foo_1.get(), interned_foo_2.get());
}
@@ -153,10 +158,11 @@
{
// Interning a weak after a strong gets you the strong.
InternTable t;
- SirtRef<String> interned_foo_1(soa.Self(), t.InternStrong(3, "foo"));
+ SirtRef<mirror::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(soa.Self(), "foo"));
- SirtRef<String> interned_foo_2(soa.Self(), t.InternWeak(foo.get()));
+ SirtRef<mirror::String> foo(soa.Self(),
+ mirror::String::AllocFromModifiedUtf8(soa.Self(), "foo"));
+ SirtRef<mirror::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/interpreter/interpreter.cc b/src/interpreter/interpreter.cc
index 820348e..65729c9 100644
--- a/src/interpreter/interpreter.cc
+++ b/src/interpreter/interpreter.cc
@@ -19,18 +19,28 @@
#include <math.h>
#include "base/logging.h"
+#include "class_linker-inl.h"
#include "common_throws.h"
#include "debugger.h"
#include "dex_instruction.h"
+#include "gc/card_table-inl.h"
#include "invoke_arg_array_builder.h"
#include "nth_caller_visitor.h"
-#include "object.h"
+#include "mirror/class.h"
+#include "mirror/class-inl.h"
+#include "mirror/field-inl.h"
+#include "mirror/abstract_method.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
#include "object_utils.h"
#include "runtime_support.h"
#include "ScopedLocalRef.h"
#include "scoped_thread_state_change.h"
#include "thread.h"
+using namespace art::mirror;
+
namespace art {
namespace interpreter {
diff --git a/src/interpreter/interpreter.h b/src/interpreter/interpreter.h
index 6990458..eee13dc 100644
--- a/src/interpreter/interpreter.h
+++ b/src/interpreter/interpreter.h
@@ -21,18 +21,20 @@
#include "locks.h"
namespace art {
-
+namespace mirror {
class AbstractMethod;
+class Object;
+} // namespace mirror
+
union JValue;
class MethodHelper;
-class Object;
class ShadowFrame;
class Thread;
namespace interpreter {
-extern void EnterInterpreterFromInvoke(Thread* self, AbstractMethod* method, Object* receiver,
- JValue* args, JValue* result)
+extern void EnterInterpreterFromInvoke(Thread* self, mirror::AbstractMethod* method,
+ mirror::Object* receiver, JValue* args, JValue* result)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
extern JValue EnterInterpreterFromDeoptimize(Thread* self, ShadowFrame& shadow_frame,
diff --git a/src/invoke_arg_array_builder.h b/src/invoke_arg_array_builder.h
index 16eedfe..19c42ac 100644
--- a/src/invoke_arg_array_builder.h
+++ b/src/invoke_arg_array_builder.h
@@ -17,7 +17,7 @@
#ifndef ART_SRC_INVOKE_ARG_ARRAY_BUILDER_H_
#define ART_SRC_INVOKE_ARG_ARRAY_BUILDER_H_
-#include "object.h"
+#include "mirror/object.h"
#include "scoped_thread_state_change.h"
namespace art {
@@ -31,7 +31,7 @@
} else if (ch == 'L') {
// Argument is a reference or an array. The shorty descriptor
// does not distinguish between these types.
- num_bytes += sizeof(Object*);
+ num_bytes += sizeof(mirror::Object*);
} else {
num_bytes += 4;
}
@@ -78,7 +78,7 @@
arg_array_[offset].SetF(va_arg(ap, jdouble));
break;
case 'L':
- arg_array_[offset].SetL(soa.Decode<Object*>(va_arg(ap, jobject)));
+ arg_array_[offset].SetL(soa.Decode<mirror::Object*>(va_arg(ap, jobject)));
break;
case 'D':
arg_array_[offset].SetD(va_arg(ap, jdouble));
@@ -113,7 +113,7 @@
arg_array_[offset].SetF(args[offset].f);
break;
case 'L':
- arg_array_[offset].SetL(soa.Decode<Object*>(args[offset].l));
+ arg_array_[offset].SetL(soa.Decode<mirror::Object*>(args[offset].l));
break;
case 'D':
arg_array_[offset].SetD(args[offset].d);
diff --git a/src/jdwp/jdwp.h b/src/jdwp/jdwp.h
index 6cac0f6..71bae08 100644
--- a/src/jdwp/jdwp.h
+++ b/src/jdwp/jdwp.h
@@ -30,8 +30,9 @@
struct iovec;
namespace art {
-
+namespace mirror {
class AbstractMethod;
+} // namespace mirror
class Thread;
namespace JDWP {
diff --git a/src/jdwp/jdwp_event.cc b/src/jdwp/jdwp_event.cc
index ba2d8d2..71e91d4 100644
--- a/src/jdwp/jdwp_event.cc
+++ b/src/jdwp/jdwp_event.cc
@@ -28,6 +28,7 @@
#include "jdwp/jdwp_expand_buf.h"
#include "jdwp/jdwp_handler.h"
#include "jdwp/jdwp_priv.h"
+#include "thread.h"
/*
General notes:
diff --git a/src/jdwp/jdwp_handler.cc b/src/jdwp/jdwp_handler.cc
index cb13695..aa5a8a0 100644
--- a/src/jdwp/jdwp_handler.cc
+++ b/src/jdwp/jdwp_handler.cc
@@ -42,6 +42,9 @@
#include "jdwp/jdwp_event.h"
#include "jdwp/jdwp_expand_buf.h"
#include "jdwp/jdwp_priv.h"
+#include "runtime.h"
+#include "thread.h"
+#include "UniquePtr.h"
namespace art {
diff --git a/src/jni_compiler_test.cc b/src/jni_compiler_test.cc
index 16976d4..4ed7898 100644
--- a/src/jni_compiler_test.cc
+++ b/src/jni_compiler_test.cc
@@ -21,6 +21,11 @@
#include "indirect_reference_table.h"
#include "jni_internal.h"
#include "mem_map.h"
+#include "mirror/class.h"
+#include "mirror/class_loader.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object_array-inl.h"
+#include "mirror/stack_trace_element.h"
#include "runtime.h"
#include "ScopedLocalRef.h"
#include "scoped_thread_state_change.h"
@@ -43,8 +48,9 @@
const char* method_name, const char* method_sig) {
ScopedObjectAccess soa(Thread::Current());
// Compile the native method before starting the runtime
- Class* c = class_linker_->FindClass("LMyClassNatives;", soa.Decode<ClassLoader*>(class_loader));
- AbstractMethod* method;
+ mirror::Class* c = class_linker_->FindClass("LMyClassNatives;",
+ soa.Decode<mirror::ClassLoader*>(class_loader));
+ mirror::AbstractMethod* method;
if (direct) {
method = c->FindDirectMethod(method_name, method_sig);
} else {
@@ -141,7 +147,7 @@
ScopedObjectAccess soa(Thread::Current());
std::string reason;
ASSERT_TRUE(
- Runtime::Current()->GetJavaVM()->LoadNativeLibrary("", soa.Decode<ClassLoader*>(class_loader_),
+ Runtime::Current()->GetJavaVM()->LoadNativeLibrary("", soa.Decode<mirror::ClassLoader*>(class_loader_),
reason)) << reason;
jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 24);
@@ -155,7 +161,7 @@
ScopedObjectAccess soa(Thread::Current());
std::string reason;
ASSERT_TRUE(
- Runtime::Current()->GetJavaVM()->LoadNativeLibrary("", soa.Decode<ClassLoader*>(class_loader_),
+ Runtime::Current()->GetJavaVM()->LoadNativeLibrary("", soa.Decode<mirror::ClassLoader*>(class_loader_),
reason)) << reason;
jint result = env_->CallStaticIntMethod(jklass_, jmethod_, 42);
@@ -548,15 +554,15 @@
// Build stack trace
jobject internal = Thread::Current()->CreateInternalStackTrace(soa);
jobjectArray ste_array = Thread::InternalStackTraceToStackTraceElementArray(env, internal);
- ObjectArray<StackTraceElement>* trace_array =
- soa.Decode<ObjectArray<StackTraceElement>*>(ste_array);
+ mirror::ObjectArray<mirror::StackTraceElement>* trace_array =
+ soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>*>(ste_array);
EXPECT_TRUE(trace_array != NULL);
EXPECT_EQ(11, trace_array->GetLength());
// Check stack trace entries have expected values
for (int32_t i = 0; i < trace_array->GetLength(); ++i) {
EXPECT_EQ(-2, trace_array->Get(i)->GetLineNumber());
- StackTraceElement* ste = trace_array->Get(i);
+ mirror::StackTraceElement* ste = trace_array->Get(i);
EXPECT_STREQ("MyClassNatives.java", ste->GetFileName()->ToModifiedUtf8().c_str());
EXPECT_STREQ("MyClassNatives", ste->GetDeclaringClass()->ToModifiedUtf8().c_str());
EXPECT_STREQ("fooI", ste->GetMethodName()->ToModifiedUtf8().c_str());
@@ -601,7 +607,7 @@
// Add 10 local references
ScopedObjectAccess soa(env);
for (int i = 0; i < 10; i++) {
- soa.AddLocalReference<jobject>(soa.Decode<Object*>(thisObj));
+ soa.AddLocalReference<jobject>(soa.Decode<mirror::Object*>(thisObj));
}
return x+1;
}
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 84b5144..0ee4c21 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -27,19 +27,28 @@
#include "base/stl_util.h"
#include "base/stringpiece.h"
#include "class_linker.h"
-#include "class_loader.h"
+#include "gc/card_table-inl.h"
#include "invoke_arg_array_builder.h"
#include "jni.h"
-#include "object.h"
+#include "mirror/class-inl.h"
+#include "mirror/class_loader.h"
+#include "mirror/field-inl.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
+#include "mirror/throwable.h"
#include "object_utils.h"
#include "runtime.h"
#include "safe_map.h"
#include "scoped_thread_state_change.h"
#include "ScopedLocalRef.h"
#include "thread.h"
+#include "utf.h"
#include "UniquePtr.h"
#include "well_known_classes.h"
+using namespace art::mirror;
+
namespace art {
static const size_t kMonitorsInitial = 32; // Arbitrary.
@@ -2533,6 +2542,11 @@
stacked_local_ref_cookies.pop_back();
}
+Offset JNIEnvExt::SegmentStateOffset() {
+ return Offset(OFFSETOF_MEMBER(JNIEnvExt, locals) +
+ IndirectReferenceTable::SegmentStateOffset().Int32Value());
+}
+
// JNI Invocation interface.
extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, void** p_env, void* vm_args) {
@@ -2860,7 +2874,7 @@
return native_method;
}
-void JavaVMExt::VisitRoots(Heap::RootVisitor* visitor, void* arg) {
+void JavaVMExt::VisitRoots(RootVisitor* visitor, void* arg) {
Thread* self = Thread::Current();
{
MutexLock mu(self, globals_lock);
diff --git a/src/jni_internal.h b/src/jni_internal.h
index 6b597ec..9b773f3 100644
--- a/src/jni_internal.h
+++ b/src/jni_internal.h
@@ -21,9 +21,9 @@
#include "base/macros.h"
#include "base/mutex.h"
-#include "heap.h"
#include "indirect_reference_table.h"
#include "reference_table.h"
+#include "root_visitor.h"
#include "runtime.h"
#include <iosfwd>
@@ -37,12 +37,13 @@
RegisterNativeMethods(env, jni_class_name, gMethods, arraysize(gMethods))
namespace art {
-
+namespace mirror {
+class AbstractMethod;
class ClassLoader;
class Field;
+}
union JValue;
class Libraries;
-class AbstractMethod;
class ScopedObjectAccess;
class Thread;
@@ -54,7 +55,8 @@
JValue InvokeWithJValues(const ScopedObjectAccess&, jobject obj, jmethodID mid, jvalue* args)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-JValue InvokeWithJValues(const ScopedObjectAccess&, Object* receiver, AbstractMethod* m, JValue* args)
+JValue InvokeWithJValues(const ScopedObjectAccess&, mirror::Object* receiver,
+ mirror::AbstractMethod* m, JValue* args)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
int ThrowNewException(JNIEnv* env, jclass exception_class, const char* msg, jobject cause);
@@ -69,14 +71,15 @@
* Returns 'true' on success. On failure, sets 'detail' to a
* human-readable description of the error.
*/
- bool LoadNativeLibrary(const std::string& path, ClassLoader* class_loader, std::string& detail)
+ bool LoadNativeLibrary(const std::string& path, mirror::ClassLoader* class_loader,
+ std::string& detail)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
/**
* Returns a pointer to the code for the native method 'm', found
* using dlsym(3) on every native library that's been loaded so far.
*/
- void* FindCodeForNativeMethod(AbstractMethod* m)
+ void* FindCodeForNativeMethod(mirror::AbstractMethod* m)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void DumpForSigQuit(std::ostream& os);
@@ -86,7 +89,7 @@
void SetCheckJniEnabled(bool enabled);
- void VisitRoots(Heap::RootVisitor*, void*);
+ void VisitRoots(RootVisitor*, void*);
Runtime* runtime;
@@ -135,10 +138,7 @@
void PushFrame(int capacity);
void PopFrame();
- static Offset SegmentStateOffset() {
- return Offset(OFFSETOF_MEMBER(JNIEnvExt, locals) +
- IndirectReferenceTable::SegmentStateOffset().Int32Value());
- }
+ static Offset SegmentStateOffset();
static Offset LocalRefCookieOffset() {
return Offset(OFFSETOF_MEMBER(JNIEnvExt, local_ref_cookie));
diff --git a/src/jni_internal_test.cc b/src/jni_internal_test.cc
index 7201233..a945ba6 100644
--- a/src/jni_internal_test.cc
+++ b/src/jni_internal_test.cc
@@ -20,6 +20,8 @@
#include <cmath>
#include "common_test.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object_array-inl.h"
#include "ScopedLocalRef.h"
#include "sirt_ref.h"
@@ -70,15 +72,17 @@
CommonTest::TearDown();
}
- AbstractMethod::InvokeStub* DoCompile(AbstractMethod*& method, Object*& receiver, bool is_static,
- const char* method_name, const char* method_signature)
+ mirror::AbstractMethod::InvokeStub* DoCompile(mirror::AbstractMethod*& method,
+ mirror::Object*& receiver,
+ bool is_static, const char* method_name,
+ const char* method_signature)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const char* class_name = is_static ? "StaticLeafMethods" : "NonStaticLeafMethods";
jobject jclass_loader(LoadDex(class_name));
Thread* self = Thread::Current();
- SirtRef<ClassLoader>
+ SirtRef<mirror::ClassLoader>
class_loader(self,
- ScopedObjectAccessUnchecked(self).Decode<ClassLoader*>(jclass_loader));
+ ScopedObjectAccessUnchecked(self).Decode<mirror::ClassLoader*>(jclass_loader));
if (is_static) {
CompileDirectMethod(class_loader.get(), class_name, method_name, method_signature);
} else {
@@ -87,7 +91,7 @@
CompileVirtualMethod(class_loader.get(), class_name, method_name, method_signature);
}
- Class* c = class_linker_->FindClass(DotToDescriptor(class_name).c_str(), class_loader.get());
+ mirror::Class* c = class_linker_->FindClass(DotToDescriptor(class_name).c_str(), class_loader.get());
CHECK(c != NULL);
method = is_static ? c->FindDirectMethod(method_name, method_signature)
@@ -96,24 +100,25 @@
receiver = (is_static ? NULL : c->AllocObject(self));
- AbstractMethod::InvokeStub* stub = method->GetInvokeStub();
+ mirror::AbstractMethod::InvokeStub* stub = method->GetInvokeStub();
CHECK(stub != NULL);
return stub;
}
void InvokeNopMethod(bool is_static) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method;
- Object* receiver;
- AbstractMethod::InvokeStub* stub = DoCompile(method, receiver, is_static, "nop", "()V");
+ mirror::AbstractMethod* method;
+ mirror::Object* receiver;
+ mirror::AbstractMethod::InvokeStub* stub = DoCompile(method, receiver, is_static, "nop", "()V");
(*stub)(method, receiver, Thread::Current(), NULL, NULL);
}
void InvokeIdentityByteMethod(bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method;
- Object* receiver;
- AbstractMethod::InvokeStub* stub = DoCompile(method, receiver, is_static, "identity", "(B)B");
+ mirror::AbstractMethod* method;
+ mirror::Object* receiver;
+ mirror::AbstractMethod::InvokeStub* stub =
+ DoCompile(method, receiver, is_static, "identity", "(B)B");
JValue args[1];
JValue result;
@@ -141,9 +146,10 @@
void InvokeIdentityIntMethod(bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method;
- Object* receiver;
- AbstractMethod::InvokeStub* stub = DoCompile(method, receiver, is_static, "identity", "(I)I");
+ mirror::AbstractMethod* method;
+ mirror::Object* receiver;
+ mirror::AbstractMethod::InvokeStub* stub =
+ DoCompile(method, receiver, is_static, "identity", "(I)I");
JValue args[1];
JValue result;
@@ -171,9 +177,10 @@
void InvokeIdentityDoubleMethod(bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method;
- Object* receiver;
- AbstractMethod::InvokeStub* stub = DoCompile(method, receiver, is_static, "identity", "(D)D");
+ mirror::AbstractMethod* method;
+ mirror::Object* receiver;
+ mirror::AbstractMethod::InvokeStub* stub =
+ DoCompile(method, receiver, is_static, "identity", "(D)D");
JValue args[1];
JValue result;
@@ -201,9 +208,10 @@
void InvokeSumIntIntMethod(bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method;
- Object* receiver;
- AbstractMethod::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(II)I");
+ mirror::AbstractMethod* method;
+ mirror::Object* receiver;
+ mirror::AbstractMethod::InvokeStub* stub =
+ DoCompile(method, receiver, is_static, "sum", "(II)I");
JValue result;
result.SetI(-1);
@@ -240,9 +248,10 @@
void InvokeSumIntIntIntMethod(bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method;
- Object* receiver;
- AbstractMethod::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(III)I");
+ mirror::AbstractMethod* method;
+ mirror::Object* receiver;
+ mirror::AbstractMethod::InvokeStub* stub =
+ DoCompile(method, receiver, is_static, "sum", "(III)I");
JValue result;
result.SetI(-1);
@@ -284,9 +293,10 @@
void InvokeSumIntIntIntIntMethod(bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method;
- Object* receiver;
- AbstractMethod::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(IIII)I");
+ mirror::AbstractMethod* method;
+ mirror::Object* receiver;
+ mirror::AbstractMethod::InvokeStub* stub =
+ DoCompile(method, receiver, is_static, "sum", "(IIII)I");
JValue result;
result.SetI(-1);
@@ -333,9 +343,10 @@
void InvokeSumIntIntIntIntIntMethod(bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method;
- Object* receiver;
- AbstractMethod::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(IIIII)I");
+ mirror::AbstractMethod* method;
+ mirror::Object* receiver;
+ mirror::AbstractMethod::InvokeStub* stub =
+ DoCompile(method, receiver, is_static, "sum", "(IIIII)I");
JValue result;
result.SetI(-1.0);
@@ -387,9 +398,10 @@
void InvokeSumDoubleDoubleMethod(bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method;
- Object* receiver;
- AbstractMethod::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(DD)D");
+ mirror::AbstractMethod* method;
+ mirror::Object* receiver;
+ mirror::AbstractMethod::InvokeStub* stub =
+ DoCompile(method, receiver, is_static, "sum", "(DD)D");
JValue args[2];
JValue result;
@@ -427,9 +439,10 @@
void InvokeSumDoubleDoubleDoubleMethod(bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method;
- Object* receiver;
- AbstractMethod::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(DDD)D");
+ mirror::AbstractMethod* method;
+ mirror::Object* receiver;
+ mirror::AbstractMethod::InvokeStub* stub =
+ DoCompile(method, receiver, is_static, "sum", "(DDD)D");
JValue args[3];
JValue result;
@@ -458,9 +471,10 @@
void InvokeSumDoubleDoubleDoubleDoubleMethod(bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method;
- Object* receiver;
- AbstractMethod::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(DDDD)D");
+ mirror::AbstractMethod* method;
+ mirror::Object* receiver;
+ mirror::AbstractMethod::InvokeStub* stub =
+ DoCompile(method, receiver, is_static, "sum", "(DDDD)D");
JValue args[4];
JValue result;
@@ -492,9 +506,10 @@
void InvokeSumDoubleDoubleDoubleDoubleDoubleMethod(bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method;
- Object* receiver;
- AbstractMethod::InvokeStub* stub = DoCompile(method, receiver, is_static, "sum", "(DDDDD)D");
+ mirror::AbstractMethod* method;
+ mirror::Object* receiver;
+ mirror::AbstractMethod::InvokeStub* stub =
+ DoCompile(method, receiver, is_static, "sum", "(DDDDD)D");
JValue args[5];
JValue result;
@@ -1270,7 +1285,7 @@
jobject outer;
jobject inner1, inner2;
ScopedObjectAccess soa(env_);
- Object* inner2_direct_pointer;
+ mirror::Object* inner2_direct_pointer;
{
env_->PushLocalFrame(4);
outer = env_->NewLocalRef(original);
@@ -1279,7 +1294,7 @@
env_->PushLocalFrame(4);
inner1 = env_->NewLocalRef(outer);
inner2 = env_->NewStringUTF("survivor");
- inner2_direct_pointer = soa.Decode<Object*>(inner2);
+ inner2_direct_pointer = soa.Decode<mirror::Object*>(inner2);
env_->PopLocalFrame(inner2);
}
@@ -1393,16 +1408,17 @@
TEST_F(JniInternalTest, StaticMainMethod) {
ScopedObjectAccess soa(Thread::Current());
jobject jclass_loader = LoadDex("Main");
- SirtRef<ClassLoader> class_loader(soa.Self(), soa.Decode<ClassLoader*>(jclass_loader));
+ SirtRef<mirror::ClassLoader>
+ class_loader(soa.Self(), soa.Decode<mirror::ClassLoader*>(jclass_loader));
CompileDirectMethod(class_loader.get(), "Main", "main", "([Ljava/lang/String;)V");
- Class* klass = class_linker_->FindClass("LMain;", class_loader.get());
+ mirror::Class* klass = class_linker_->FindClass("LMain;", class_loader.get());
ASSERT_TRUE(klass != NULL);
- AbstractMethod* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
+ mirror::AbstractMethod* method = klass->FindDirectMethod("main", "([Ljava/lang/String;)V");
ASSERT_TRUE(method != NULL);
- AbstractMethod::InvokeStub* stub = method->GetInvokeStub();
+ mirror::AbstractMethod::InvokeStub* stub = method->GetInvokeStub();
JValue args[1];
args[0].SetL(NULL);
diff --git a/src/jobject_comparator.cc b/src/jobject_comparator.cc
index edd0727..738a186 100644
--- a/src/jobject_comparator.cc
+++ b/src/jobject_comparator.cc
@@ -16,7 +16,9 @@
#include "jobject_comparator.h"
-#include "object.h"
+#include "mirror/array-inl.h"
+#include "mirror/class.h"
+#include "mirror/object-inl.h"
#include "scoped_thread_state_change.h"
namespace art {
@@ -29,8 +31,8 @@
return false;
}
ScopedObjectAccess soa(Thread::Current());
- Object* obj1 = soa.Decode<Object*>(jobj1);
- Object* obj2 = soa.Decode<Object*>(jobj2);
+ mirror::Object* obj1 = soa.Decode<mirror::Object*>(jobj1);
+ mirror::Object* obj2 = soa.Decode<mirror::Object*>(jobj2);
if (obj1 == NULL) {
return true;
} else if (obj2 == NULL) {
diff --git a/src/jvalue.h b/src/jvalue.h
index a7a1795..fa85937 100644
--- a/src/jvalue.h
+++ b/src/jvalue.h
@@ -20,8 +20,9 @@
#include "base/macros.h"
namespace art {
-
+namespace mirror {
class Object;
+} // namespace mirror
union PACKED(4) JValue {
// We default initialize JValue instances to all-zeros.
@@ -47,8 +48,8 @@
int64_t GetJ() const { return j; }
void SetJ(int64_t new_j) { j = new_j; }
- Object* GetL() const { return l; }
- void SetL(Object* new_l) { l = new_l; }
+ mirror::Object* GetL() const { return l; }
+ void SetL(mirror::Object* new_l) { l = new_l; }
int16_t GetS() const { return s; }
void SetS(int16_t new_s) {
@@ -67,7 +68,7 @@
int64_t j;
float f;
double d;
- Object* l;
+ mirror::Object* l;
};
} // namespace art
diff --git a/src/mirror/abstract_method-inl.h b/src/mirror/abstract_method-inl.h
new file mode 100644
index 0000000..efb7c03
--- /dev/null
+++ b/src/mirror/abstract_method-inl.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_METHOD_INL_H_
+#define ART_SRC_MIRROR_METHOD_INL_H_
+
+#include "abstract_method.h"
+
+#include "array.h"
+#include "dex_file.h"
+#include "runtime.h"
+
+namespace art {
+namespace mirror {
+
+inline Class* AbstractMethod::GetDeclaringClass() const {
+ Class* result = GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, declaring_class_), false);
+ DCHECK(result != NULL) << this;
+ DCHECK(result->IsIdxLoaded() || result->IsErroneous()) << this;
+ return result;
+}
+
+inline void AbstractMethod::SetDeclaringClass(Class *new_declaring_class) {
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, declaring_class_), new_declaring_class, false);
+}
+
+inline uint32_t AbstractMethod::GetAccessFlags() const {
+ DCHECK(GetDeclaringClass()->IsIdxLoaded() || GetDeclaringClass()->IsErroneous());
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, access_flags_), false);
+}
+
+inline uint16_t AbstractMethod::GetMethodIndex() const {
+ DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous());
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, method_index_), false);
+}
+
+inline uint32_t AbstractMethod::GetDexMethodIndex() const {
+ DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, method_dex_index_), false);
+}
+
+inline uint32_t AbstractMethod::GetCodeSize() const {
+ DCHECK(!IsRuntimeMethod() && !IsProxyMethod()) << PrettyMethod(this);
+ uintptr_t code = reinterpret_cast<uintptr_t>(GetCode());
+ if (code == 0) {
+ return 0;
+ }
+ // TODO: make this Thumb2 specific
+ code &= ~0x1;
+ return reinterpret_cast<uint32_t*>(code)[-1];
+}
+
+inline bool AbstractMethod::CheckIncompatibleClassChange(InvokeType type) {
+ switch (type) {
+ case kStatic:
+ return !IsStatic();
+ case kDirect:
+ return !IsDirect() || IsStatic();
+ case kVirtual: {
+ Class* methods_class = GetDeclaringClass();
+ return IsDirect() || (methods_class->IsInterface() && !IsMiranda());
+ }
+ case kSuper:
+ return false; // TODO: appropriate checks for call to super class.
+ case kInterface: {
+ Class* methods_class = GetDeclaringClass();
+ return IsDirect() || !(methods_class->IsInterface() || methods_class->IsObjectClass());
+ }
+ default:
+ LOG(FATAL) << "Unreachable - invocation type: " << type;
+ return true;
+ }
+}
+
+inline void AbstractMethod::AssertPcIsWithinCode(uintptr_t pc) const {
+ if (!kIsDebugBuild) {
+ return;
+ }
+ if (IsNative() || IsRuntimeMethod() || IsProxyMethod()) {
+ return;
+ }
+ Runtime* runtime = Runtime::Current();
+ if (GetCode() == runtime->GetResolutionStubArray(Runtime::kStaticMethod)->GetData()) {
+ return;
+ }
+ DCHECK(IsWithinCode(pc))
+ << PrettyMethod(this)
+ << " pc=" << std::hex << pc
+ << " code=" << GetCode()
+ << " size=" << GetCodeSize();
+}
+
+inline uint32_t AbstractMethod::GetOatCodeOffset() const {
+ DCHECK(!Runtime::Current()->IsStarted());
+ return reinterpret_cast<uint32_t>(GetCode());
+}
+
+inline void AbstractMethod::SetOatCodeOffset(uint32_t code_offset) {
+ DCHECK(!Runtime::Current()->IsStarted());
+ SetCode(reinterpret_cast<void*>(code_offset));
+}
+
+inline uint32_t AbstractMethod::GetOatMappingTableOffset() const {
+ DCHECK(!Runtime::Current()->IsStarted());
+ return reinterpret_cast<uint32_t>(GetMappingTableRaw());
+}
+
+inline void AbstractMethod::SetOatMappingTableOffset(uint32_t mapping_table_offset) {
+ DCHECK(!Runtime::Current()->IsStarted());
+ SetMappingTable(reinterpret_cast<const uint32_t*>(mapping_table_offset));
+}
+
+inline uint32_t AbstractMethod::GetOatVmapTableOffset() const {
+ DCHECK(!Runtime::Current()->IsStarted());
+ return reinterpret_cast<uint32_t>(GetVmapTableRaw());
+}
+
+inline void AbstractMethod::SetOatVmapTableOffset(uint32_t vmap_table_offset) {
+ DCHECK(!Runtime::Current()->IsStarted());
+ SetVmapTable(reinterpret_cast<uint16_t*>(vmap_table_offset));
+}
+
+inline void AbstractMethod::SetOatNativeGcMapOffset(uint32_t gc_map_offset) {
+ DCHECK(!Runtime::Current()->IsStarted());
+ SetNativeGcMap(reinterpret_cast<uint8_t*>(gc_map_offset));
+}
+
+inline uint32_t AbstractMethod::GetOatNativeGcMapOffset() const {
+ DCHECK(!Runtime::Current()->IsStarted());
+ return reinterpret_cast<uint32_t>(GetNativeGcMap());
+}
+
+inline uint32_t AbstractMethod::GetOatInvokeStubOffset() const {
+ DCHECK(!Runtime::Current()->IsStarted());
+ return reinterpret_cast<uint32_t>(GetInvokeStub());
+}
+
+inline void AbstractMethod::SetOatInvokeStubOffset(uint32_t invoke_stub_offset) {
+ DCHECK(!Runtime::Current()->IsStarted());
+ SetInvokeStub(reinterpret_cast<InvokeStub*>(invoke_stub_offset));
+}
+
+inline bool AbstractMethod::IsRuntimeMethod() const {
+ return GetDexMethodIndex() == DexFile::kDexNoIndex16;
+}
+
+inline bool AbstractMethod::IsCalleeSaveMethod() const {
+ if (!IsRuntimeMethod()) {
+ return false;
+ }
+ Runtime* runtime = Runtime::Current();
+ bool result = false;
+ for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
+ if (this == runtime->GetCalleeSaveMethod(Runtime::CalleeSaveType(i))) {
+ result = true;
+ break;
+ }
+ }
+ return result;
+}
+
+inline bool AbstractMethod::IsResolutionMethod() const {
+ bool result = this == Runtime::Current()->GetResolutionMethod();
+ // Check that if we do think it is phony it looks like the resolution method.
+ DCHECK(!result || IsRuntimeMethod());
+ return result;
+}
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_METHOD_INL_H_
diff --git a/src/mirror/abstract_method.cc b/src/mirror/abstract_method.cc
new file mode 100644
index 0000000..4641941
--- /dev/null
+++ b/src/mirror/abstract_method.cc
@@ -0,0 +1,376 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "abstract_method.h"
+
+#include "abstract_method-inl.h"
+#include "class-inl.h"
+#include "base/stringpiece.h"
+#include "gc/card_table-inl.h"
+#include "interpreter/interpreter.h"
+#include "jni_internal.h"
+#include "object-inl.h"
+#include "object_array.h"
+#include "object_array-inl.h"
+#include "string.h"
+#include "object_utils.h"
+
+namespace art {
+namespace mirror {
+
+// TODO: get global references for these
+Class* AbstractMethod::java_lang_reflect_Constructor_ = NULL;
+Class* AbstractMethod::java_lang_reflect_Method_ = NULL;
+
+InvokeType AbstractMethod::GetInvokeType() const {
+ // TODO: kSuper?
+ if (GetDeclaringClass()->IsInterface()) {
+ return kInterface;
+ } else if (IsStatic()) {
+ return kStatic;
+ } else if (IsDirect()) {
+ return kDirect;
+ } else {
+ return kVirtual;
+ }
+}
+
+void AbstractMethod::SetClasses(Class* java_lang_reflect_Constructor, Class* java_lang_reflect_Method) {
+ CHECK(java_lang_reflect_Constructor_ == NULL);
+ CHECK(java_lang_reflect_Constructor != NULL);
+ java_lang_reflect_Constructor_ = java_lang_reflect_Constructor;
+
+ CHECK(java_lang_reflect_Method_ == NULL);
+ CHECK(java_lang_reflect_Method != NULL);
+ java_lang_reflect_Method_ = java_lang_reflect_Method;
+}
+
+void AbstractMethod::ResetClasses() {
+ CHECK(java_lang_reflect_Constructor_ != NULL);
+ java_lang_reflect_Constructor_ = NULL;
+
+ CHECK(java_lang_reflect_Method_ != NULL);
+ java_lang_reflect_Method_ = NULL;
+}
+
+ObjectArray<String>* AbstractMethod::GetDexCacheStrings() const {
+ return GetFieldObject<ObjectArray<String>*>(
+ OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_strings_), false);
+}
+
+void AbstractMethod::SetDexCacheStrings(ObjectArray<String>* new_dex_cache_strings) {
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_strings_),
+ new_dex_cache_strings, false);
+}
+
+ObjectArray<AbstractMethod>* AbstractMethod::GetDexCacheResolvedMethods() const {
+ return GetFieldObject<ObjectArray<AbstractMethod>*>(
+ OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_resolved_methods_), false);
+}
+
+void AbstractMethod::SetDexCacheResolvedMethods(ObjectArray<AbstractMethod>* new_dex_cache_methods) {
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_resolved_methods_),
+ new_dex_cache_methods, false);
+}
+
+ObjectArray<Class>* AbstractMethod::GetDexCacheResolvedTypes() const {
+ return GetFieldObject<ObjectArray<Class>*>(
+ OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_resolved_types_), false);
+}
+
+void AbstractMethod::SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cache_classes) {
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_resolved_types_),
+ new_dex_cache_classes, false);
+}
+
+ObjectArray<StaticStorageBase>* AbstractMethod::GetDexCacheInitializedStaticStorage() const {
+ return GetFieldObject<ObjectArray<StaticStorageBase>*>(
+ OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_initialized_static_storage_),
+ false);
+}
+
+void AbstractMethod::SetDexCacheInitializedStaticStorage(ObjectArray<StaticStorageBase>* new_value) {
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_initialized_static_storage_),
+ new_value, false);
+}
+
+size_t AbstractMethod::NumArgRegisters(const StringPiece& shorty) {
+ CHECK_LE(1, shorty.length());
+ uint32_t num_registers = 0;
+ for (int i = 1; i < shorty.length(); ++i) {
+ char ch = shorty[i];
+ if (ch == 'D' || ch == 'J') {
+ num_registers += 2;
+ } else {
+ num_registers += 1;
+ }
+ }
+ return num_registers;
+}
+
+bool AbstractMethod::IsProxyMethod() const {
+ return GetDeclaringClass()->IsProxyClass();
+}
+
+AbstractMethod* AbstractMethod::FindOverriddenMethod() const {
+ if (IsStatic()) {
+ return NULL;
+ }
+ Class* declaring_class = GetDeclaringClass();
+ Class* super_class = declaring_class->GetSuperClass();
+ uint16_t method_index = GetMethodIndex();
+ ObjectArray<AbstractMethod>* super_class_vtable = super_class->GetVTable();
+ AbstractMethod* result = NULL;
+ // Did this method override a super class method? If so load the result from the super class'
+ // vtable
+ if (super_class_vtable != NULL && method_index < super_class_vtable->GetLength()) {
+ result = super_class_vtable->Get(method_index);
+ } else {
+ // Method didn't override superclass method so search interfaces
+ if (IsProxyMethod()) {
+ result = GetDexCacheResolvedMethods()->Get(GetDexMethodIndex());
+ CHECK_EQ(result,
+ Runtime::Current()->GetClassLinker()->FindMethodForProxy(GetDeclaringClass(), this));
+ } else {
+ MethodHelper mh(this);
+ MethodHelper interface_mh;
+ IfTable* iftable = GetDeclaringClass()->GetIfTable();
+ for (size_t i = 0; i < iftable->Count() && result == NULL; i++) {
+ Class* interface = iftable->GetInterface(i);
+ for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
+ AbstractMethod* interface_method = interface->GetVirtualMethod(j);
+ interface_mh.ChangeMethod(interface_method);
+ if (mh.HasSameNameAndSignature(&interface_mh)) {
+ result = interface_method;
+ break;
+ }
+ }
+ }
+ }
+ }
+#ifndef NDEBUG
+ MethodHelper result_mh(result);
+ DCHECK(result == NULL || MethodHelper(this).HasSameNameAndSignature(&result_mh));
+#endif
+ return result;
+}
+
+static const void* GetOatCode(const AbstractMethod* m)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ Runtime* runtime = Runtime::Current();
+ const void* code = m->GetCode();
+ // Peel off any method tracing trampoline.
+ if (runtime->IsMethodTracingActive() && runtime->GetInstrumentation()->GetSavedCodeFromMap(m) != NULL) {
+ code = runtime->GetInstrumentation()->GetSavedCodeFromMap(m);
+ }
+ // Peel off any resolution stub.
+ if (code == runtime->GetResolutionStubArray(Runtime::kStaticMethod)->GetData()) {
+ code = runtime->GetClassLinker()->GetOatCodeFor(m);
+ }
+ return code;
+}
+
+uintptr_t AbstractMethod::NativePcOffset(const uintptr_t pc) const {
+ return pc - reinterpret_cast<uintptr_t>(GetOatCode(this));
+}
+
+// Find the lowest-address native safepoint pc for a given dex pc
+uintptr_t AbstractMethod::ToFirstNativeSafepointPc(const uint32_t dex_pc) const {
+#if !defined(ART_USE_LLVM_COMPILER)
+ const uint32_t* mapping_table = GetPcToDexMappingTable();
+ if (mapping_table == NULL) {
+ DCHECK(IsNative() || IsCalleeSaveMethod() || IsProxyMethod()) << PrettyMethod(this);
+ return DexFile::kDexNoIndex; // Special no mapping case
+ }
+ size_t mapping_table_length = GetPcToDexMappingTableLength();
+ for (size_t i = 0; i < mapping_table_length; i += 2) {
+ if (mapping_table[i + 1] == dex_pc) {
+ return mapping_table[i] + reinterpret_cast<uintptr_t>(GetOatCode(this));
+ }
+ }
+ LOG(FATAL) << "Failed to find native offset for dex pc 0x" << std::hex << dex_pc
+ << " in " << PrettyMethod(this);
+ return 0;
+#else
+ // Compiler LLVM doesn't use the machine pc, we just use dex pc instead.
+ return static_cast<uint32_t>(dex_pc);
+#endif
+}
+
+uint32_t AbstractMethod::ToDexPc(const uintptr_t pc) const {
+#if !defined(ART_USE_LLVM_COMPILER)
+ const uint32_t* mapping_table = GetPcToDexMappingTable();
+ if (mapping_table == NULL) {
+ DCHECK(IsNative() || IsCalleeSaveMethod() || IsProxyMethod()) << PrettyMethod(this);
+ return DexFile::kDexNoIndex; // Special no mapping case
+ }
+ size_t mapping_table_length = GetPcToDexMappingTableLength();
+ uint32_t sought_offset = pc - reinterpret_cast<uintptr_t>(GetOatCode(this));
+ for (size_t i = 0; i < mapping_table_length; i += 2) {
+ if (mapping_table[i] == sought_offset) {
+ return mapping_table[i + 1];
+ }
+ }
+ LOG(ERROR) << "Failed to find Dex offset for PC offset " << reinterpret_cast<void*>(sought_offset)
+ << "(PC " << reinterpret_cast<void*>(pc) << ") in " << PrettyMethod(this);
+ return DexFile::kDexNoIndex;
+#else
+ // Compiler LLVM doesn't use the machine pc, we just use dex pc instead.
+ return static_cast<uint32_t>(pc);
+#endif
+}
+
+uintptr_t AbstractMethod::ToNativePc(const uint32_t dex_pc) const {
+ const uint32_t* mapping_table = GetDexToPcMappingTable();
+ if (mapping_table == NULL) {
+ DCHECK_EQ(dex_pc, 0U);
+ return 0; // Special no mapping/pc == 0 case
+ }
+ size_t mapping_table_length = GetDexToPcMappingTableLength();
+ for (size_t i = 0; i < mapping_table_length; i += 2) {
+ uint32_t map_offset = mapping_table[i];
+ uint32_t map_dex_offset = mapping_table[i + 1];
+ if (map_dex_offset == dex_pc) {
+ return reinterpret_cast<uintptr_t>(GetOatCode(this)) + map_offset;
+ }
+ }
+ LOG(FATAL) << "Looking up Dex PC not contained in method, 0x" << std::hex << dex_pc
+ << " in " << PrettyMethod(this);
+ return 0;
+}
+
+uint32_t AbstractMethod::FindCatchBlock(Class* exception_type, uint32_t dex_pc) const {
+ MethodHelper mh(this);
+ const DexFile::CodeItem* code_item = mh.GetCodeItem();
+ // Iterate over the catch handlers associated with dex_pc
+ for (CatchHandlerIterator it(*code_item, dex_pc); it.HasNext(); it.Next()) {
+ uint16_t iter_type_idx = it.GetHandlerTypeIndex();
+ // Catch all case
+ if (iter_type_idx == DexFile::kDexNoIndex16) {
+ return it.GetHandlerAddress();
+ }
+ // Does this catch exception type apply?
+ Class* iter_exception_type = mh.GetDexCacheResolvedType(iter_type_idx);
+ if (iter_exception_type == NULL) {
+ // The verifier should take care of resolving all exception classes early
+ LOG(WARNING) << "Unresolved exception class when finding catch block: "
+ << mh.GetTypeDescriptorFromTypeIdx(iter_type_idx);
+ } else if (iter_exception_type->IsAssignableFrom(exception_type)) {
+ return it.GetHandlerAddress();
+ }
+ }
+ // Handler not found
+ return DexFile::kDexNoIndex;
+}
+
+void AbstractMethod::Invoke(Thread* self, Object* receiver, JValue* args, JValue* result) {
+ if (kIsDebugBuild) {
+ self->AssertThreadSuspensionIsAllowable();
+ CHECK_EQ(kRunnable, self->GetState());
+ }
+
+ // Push a transition back into managed code onto the linked list in thread.
+ ManagedStack fragment;
+ self->PushManagedStackFragment(&fragment);
+
+ // Call the invoke stub associated with the method.
+ // Pass everything as arguments.
+ AbstractMethod::InvokeStub* stub = GetInvokeStub();
+
+ if (UNLIKELY(!Runtime::Current()->IsStarted())){
+ LOG(INFO) << "Not invoking " << PrettyMethod(this) << " for a runtime that isn't started";
+ if (result != NULL) {
+ result->SetJ(0);
+ }
+ } else {
+ bool interpret = self->ReadFlag(kEnterInterpreter) && !IsNative() && !IsProxyMethod();
+ const bool kLogInvocationStartAndReturn = false;
+ if (!interpret && GetCode() != NULL && stub != NULL) {
+ if (kLogInvocationStartAndReturn) {
+ LOG(INFO) << StringPrintf("Invoking '%s' code=%p stub=%p",
+ PrettyMethod(this).c_str(), GetCode(), stub);
+ }
+ (*stub)(this, receiver, self, args, result);
+ if (kLogInvocationStartAndReturn) {
+ LOG(INFO) << StringPrintf("Returned '%s' code=%p stub=%p",
+ PrettyMethod(this).c_str(), GetCode(), stub);
+ }
+ } else {
+ const bool kInterpretMethodsWithNoCode = false;
+ if (interpret || kInterpretMethodsWithNoCode) {
+ if (kLogInvocationStartAndReturn) {
+ LOG(INFO) << "Interpreting " << PrettyMethod(this) << "'";
+ }
+ art::interpreter::EnterInterpreterFromInvoke(self, this, receiver, args, result);
+ if (kLogInvocationStartAndReturn) {
+ LOG(INFO) << "Returned '" << PrettyMethod(this) << "'";
+ }
+ } else {
+ LOG(INFO) << "Not invoking '" << PrettyMethod(this)
+ << "' code=" << reinterpret_cast<const void*>(GetCode())
+ << " stub=" << reinterpret_cast<void*>(stub);
+ if (result != NULL) {
+ result->SetJ(0);
+ }
+ }
+ }
+ }
+
+ // Pop transition.
+ self->PopManagedStackFragment(fragment);
+}
+
+bool AbstractMethod::IsRegistered() const {
+ void* native_method = GetFieldPtr<void*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, native_method_), false);
+ CHECK(native_method != NULL);
+ void* jni_stub = Runtime::Current()->GetJniDlsymLookupStub()->GetData();
+ return native_method != jni_stub;
+}
+
+void AbstractMethod::RegisterNative(Thread* self, const void* native_method) {
+ DCHECK(Thread::Current() == self);
+ CHECK(IsNative()) << PrettyMethod(this);
+ CHECK(native_method != NULL) << PrettyMethod(this);
+ if (!self->GetJniEnv()->vm->work_around_app_jni_bugs) {
+ SetNativeMethod(native_method);
+ } else {
+ // We've been asked to associate this method with the given native method but are working
+ // around JNI bugs, that include not giving Object** SIRT references to native methods. Direct
+ // the native method to runtime support and store the target somewhere runtime support will
+ // find it.
+#if defined(__arm__) && !defined(ART_USE_LLVM_COMPILER)
+ SetNativeMethod(native_method);
+#else
+ UNIMPLEMENTED(FATAL);
+#endif
+ SetFieldPtr<const uint8_t*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, native_gc_map_),
+ reinterpret_cast<const uint8_t*>(native_method), false);
+ }
+}
+
+void AbstractMethod::UnregisterNative(Thread* self) {
+ CHECK(IsNative()) << PrettyMethod(this);
+ // restore stub to lookup native pointer via dlsym
+ RegisterNative(self, Runtime::Current()->GetJniDlsymLookupStub()->GetData());
+}
+
+void AbstractMethod::SetNativeMethod(const void* native_method) {
+ SetFieldPtr<const void*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, native_method_),
+ native_method, false);
+}
+
+} // namespace mirror
+} // namespace art
diff --git a/src/mirror/abstract_method.h b/src/mirror/abstract_method.h
new file mode 100644
index 0000000..1d57abb
--- /dev/null
+++ b/src/mirror/abstract_method.h
@@ -0,0 +1,524 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_METHOD_H_
+#define ART_SRC_MIRROR_METHOD_H_
+
+#include "class.h"
+#include "invoke_type.h"
+#include "locks.h"
+#include "modifiers.h"
+#include "object.h"
+
+namespace art {
+
+struct AbstractMethodOffsets;
+struct ConstructorMethodOffsets;
+union JValue;
+struct MethodClassOffsets;
+struct MethodOffsets;
+class StringPiece;
+
+namespace mirror {
+
+class StaticStorageBase;
+
+// C++ mirror of java.lang.reflect.Method and java.lang.reflect.Constructor
+class MANAGED AbstractMethod : public Object {
+ public:
+ // A function that invokes a method with an array of its arguments.
+ typedef void InvokeStub(const AbstractMethod* method,
+ Object* obj,
+ Thread* thread,
+ JValue* args,
+ JValue* result);
+
+ Class* GetDeclaringClass() const;
+
+ void SetDeclaringClass(Class *new_declaring_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static MemberOffset DeclaringClassOffset() {
+ return MemberOffset(OFFSETOF_MEMBER(AbstractMethod, declaring_class_));
+ }
+
+ uint32_t GetAccessFlags() const;
+
+ void SetAccessFlags(uint32_t new_access_flags) {
+ SetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, access_flags_), new_access_flags, false);
+ }
+
+ // Approximate what kind of method call would be used for this method.
+ InvokeType GetInvokeType() const;
+
+ // Returns true if the method is declared public.
+ bool IsPublic() const {
+ return (GetAccessFlags() & kAccPublic) != 0;
+ }
+
+ // Returns true if the method is declared private.
+ bool IsPrivate() const {
+ return (GetAccessFlags() & kAccPrivate) != 0;
+ }
+
+ // Returns true if the method is declared static.
+ bool IsStatic() const {
+ return (GetAccessFlags() & kAccStatic) != 0;
+ }
+
+ // Returns true if the method is a constructor.
+ bool IsConstructor() const {
+ return (GetAccessFlags() & kAccConstructor) != 0;
+ }
+
+ // Returns true if the method is static, private, or a constructor.
+ bool IsDirect() const {
+ return IsDirect(GetAccessFlags());
+ }
+
+ static bool IsDirect(uint32_t access_flags) {
+ return (access_flags & (kAccStatic | kAccPrivate | kAccConstructor)) != 0;
+ }
+
+ // Returns true if the method is declared synchronized.
+ bool IsSynchronized() const {
+ uint32_t synchonized = kAccSynchronized | kAccDeclaredSynchronized;
+ return (GetAccessFlags() & synchonized) != 0;
+ }
+
+ bool IsFinal() const {
+ return (GetAccessFlags() & kAccFinal) != 0;
+ }
+
+ bool IsMiranda() const {
+ return (GetAccessFlags() & kAccMiranda) != 0;
+ }
+
+ bool IsNative() const {
+ return (GetAccessFlags() & kAccNative) != 0;
+ }
+
+ bool IsAbstract() const {
+ return (GetAccessFlags() & kAccAbstract) != 0;
+ }
+
+ bool IsSynthetic() const {
+ return (GetAccessFlags() & kAccSynthetic) != 0;
+ }
+
+ bool IsProxyMethod() const;
+
+ bool CheckIncompatibleClassChange(InvokeType type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ uint16_t GetMethodIndex() const;
+
+ size_t GetVtableIndex() const {
+ return GetMethodIndex();
+ }
+
+ void SetMethodIndex(uint16_t new_method_index) {
+ SetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, method_index_), new_method_index, false);
+ }
+
+ static MemberOffset MethodIndexOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, method_index_);
+ }
+
+ uint32_t GetCodeItemOffset() const {
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, code_item_offset_), false);
+ }
+
+ void SetCodeItemOffset(uint32_t new_code_off) {
+ SetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, code_item_offset_), new_code_off, false);
+ }
+
+ // Number of 32bit registers that would be required to hold all the arguments
+ static size_t NumArgRegisters(const StringPiece& shorty);
+
+ uint32_t GetDexMethodIndex() const;
+
+ void SetDexMethodIndex(uint32_t new_idx) {
+ SetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, method_dex_index_), new_idx, false);
+ }
+
+ ObjectArray<String>* GetDexCacheStrings() const;
+ void SetDexCacheStrings(ObjectArray<String>* new_dex_cache_strings)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static MemberOffset DexCacheStringsOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_strings_);
+ }
+
+ static MemberOffset DexCacheResolvedMethodsOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_resolved_methods_);
+ }
+
+ static MemberOffset DexCacheResolvedTypesOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_resolved_types_);
+ }
+
+ static MemberOffset DexCacheInitializedStaticStorageOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(AbstractMethod,
+ dex_cache_initialized_static_storage_);
+ }
+
+ ObjectArray<AbstractMethod>* GetDexCacheResolvedMethods() const;
+ void SetDexCacheResolvedMethods(ObjectArray<AbstractMethod>* new_dex_cache_methods)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ ObjectArray<Class>* GetDexCacheResolvedTypes() const;
+ void SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cache_types)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ ObjectArray<StaticStorageBase>* GetDexCacheInitializedStaticStorage() const;
+ void SetDexCacheInitializedStaticStorage(ObjectArray<StaticStorageBase>* new_value)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Find the method that this method overrides
+ AbstractMethod* FindOverriddenMethod() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void Invoke(Thread* self, Object* receiver, JValue* args, JValue* result)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ const void* GetCode() const {
+ return GetFieldPtr<const void*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, code_), false);
+ }
+
+ void SetCode(const void* code) {
+ SetFieldPtr<const void*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, code_), code, false);
+ }
+
+ uint32_t GetCodeSize() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ bool IsWithinCode(uintptr_t pc) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ uintptr_t code = reinterpret_cast<uintptr_t>(GetCode());
+ if (code == 0) {
+ return pc == 0;
+ }
+ /*
+ * During a stack walk, a return PC may point to the end of the code + 1
+ * (in the case that the last instruction is a call that isn't expected to
+ * return. Thus, we check <= code + GetCodeSize().
+ */
+ return (code <= pc && pc <= code + GetCodeSize());
+ }
+
+ void AssertPcIsWithinCode(uintptr_t pc) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ uint32_t GetOatCodeOffset() const;
+
+ void SetOatCodeOffset(uint32_t code_offset);
+
+ static MemberOffset GetCodeOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, code_);
+ }
+
+ const uint32_t* GetMappingTable() const {
+ const uint32_t* map = GetMappingTableRaw();
+ if (map == NULL) {
+ return map;
+ }
+ return map + 1;
+ }
+
+ uint32_t GetPcToDexMappingTableLength() const {
+ const uint32_t* map = GetMappingTableRaw();
+ if (map == NULL) {
+ return 0;
+ }
+ return map[2];
+ }
+
+ const uint32_t* GetPcToDexMappingTable() const {
+ const uint32_t* map = GetMappingTableRaw();
+ if (map == NULL) {
+ return map;
+ }
+ return map + 3;
+ }
+
+
+ uint32_t GetDexToPcMappingTableLength() const {
+ const uint32_t* map = GetMappingTableRaw();
+ if (map == NULL) {
+ return 0;
+ }
+ return map[1] - map[2];
+ }
+
+ const uint32_t* GetDexToPcMappingTable() const {
+ const uint32_t* map = GetMappingTableRaw();
+ if (map == NULL) {
+ return map;
+ }
+ return map + 3 + map[2];
+ }
+
+
+ const uint32_t* GetMappingTableRaw() const {
+ return GetFieldPtr<const uint32_t*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, mapping_table_), false);
+ }
+
+ void SetMappingTable(const uint32_t* mapping_table) {
+ SetFieldPtr<const uint32_t*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, mapping_table_),
+ mapping_table, false);
+ }
+
+ uint32_t GetOatMappingTableOffset() const;
+
+ void SetOatMappingTableOffset(uint32_t mapping_table_offset);
+
+ // Callers should wrap the uint16_t* in a VmapTable instance for convenient access.
+ const uint16_t* GetVmapTableRaw() const {
+ return GetFieldPtr<const uint16_t*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, vmap_table_), false);
+ }
+
+ void SetVmapTable(const uint16_t* vmap_table) {
+ SetFieldPtr<const uint16_t*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, vmap_table_), vmap_table, false);
+ }
+
+ uint32_t GetOatVmapTableOffset() const;
+
+ void SetOatVmapTableOffset(uint32_t vmap_table_offset);
+
+ const uint8_t* GetNativeGcMap() const {
+ return GetFieldPtr<uint8_t*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, native_gc_map_), false);
+ }
+ void SetNativeGcMap(const uint8_t* data) {
+ SetFieldPtr<const uint8_t*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, native_gc_map_), data,
+ false);
+ }
+
+ // When building the oat need a convenient place to stuff the offset of the native GC map.
+ void SetOatNativeGcMapOffset(uint32_t gc_map_offset);
+ uint32_t GetOatNativeGcMapOffset() const;
+
+ size_t GetFrameSizeInBytes() const {
+ DCHECK_EQ(sizeof(size_t), sizeof(uint32_t));
+ size_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, frame_size_in_bytes_), false);
+ DCHECK_LE(static_cast<size_t>(kStackAlignment), result);
+ return result;
+ }
+
+ void SetFrameSizeInBytes(size_t new_frame_size_in_bytes) {
+ DCHECK_EQ(sizeof(size_t), sizeof(uint32_t));
+ SetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, frame_size_in_bytes_),
+ new_frame_size_in_bytes, false);
+ }
+
+ size_t GetReturnPcOffsetInBytes() const {
+ return GetFrameSizeInBytes() - kPointerSize;
+ }
+
+ bool IsRegistered() const;
+
+ void RegisterNative(Thread* self, const void* native_method)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void UnregisterNative(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static MemberOffset NativeMethodOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, native_method_);
+ }
+
+ const void* GetNativeMethod() const {
+ return reinterpret_cast<const void*>(GetField32(NativeMethodOffset(), false));
+ }
+
+ void SetNativeMethod(const void*);
+
+ // Native to managed invocation stub entry point
+ InvokeStub* GetInvokeStub() const {
+ InvokeStub* result = GetFieldPtr<InvokeStub*>(
+ OFFSET_OF_OBJECT_MEMBER(AbstractMethod, invoke_stub_), false);
+ // TODO: DCHECK(result != NULL); should be ahead of time compiled
+ return result;
+ }
+
+ void SetInvokeStub(InvokeStub* invoke_stub) {
+ SetFieldPtr<InvokeStub*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, invoke_stub_),
+ invoke_stub, false);
+ }
+
+ uint32_t GetInvokeStubSize() const {
+ uintptr_t invoke_stub = reinterpret_cast<uintptr_t>(GetInvokeStub());
+ if (invoke_stub == 0) {
+ return 0;
+ }
+ // TODO: make this Thumb2 specific
+ invoke_stub &= ~0x1;
+ return reinterpret_cast<const uint32_t*>(invoke_stub)[-1];
+ }
+
+ uint32_t GetOatInvokeStubOffset() const;
+ void SetOatInvokeStubOffset(uint32_t invoke_stub_offset);
+
+ static MemberOffset GetInvokeStubOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, invoke_stub_);
+ }
+
+ static MemberOffset GetMethodIndexOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, method_index_);
+ }
+
+ uint32_t GetCoreSpillMask() const {
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, core_spill_mask_), false);
+ }
+
+ void SetCoreSpillMask(uint32_t core_spill_mask) {
+ // Computed during compilation
+ SetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, core_spill_mask_), core_spill_mask, false);
+ }
+
+ uint32_t GetFpSpillMask() const {
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, fp_spill_mask_), false);
+ }
+
+ void SetFpSpillMask(uint32_t fp_spill_mask) {
+ // Computed during compilation
+ SetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, fp_spill_mask_), fp_spill_mask, false);
+ }
+
+ // Is this a CalleSaveMethod or ResolutionMethod and therefore doesn't adhere to normal
+ // conventions for a method of managed code. Returns false for Proxy methods.
+ bool IsRuntimeMethod() const;
+
+ // Is this a hand crafted method used for something like describing callee saves?
+ bool IsCalleeSaveMethod() const;
+
+ bool IsResolutionMethod() const;
+
+ uintptr_t NativePcOffset(const uintptr_t pc) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Converts a native PC to a dex PC.
+ uint32_t ToDexPc(const uintptr_t pc) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Converts a dex PC to a native PC.
+ uintptr_t ToNativePc(const uint32_t dex_pc) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Converts a dex PC to the first corresponding safepoint PC.
+ uintptr_t ToFirstNativeSafepointPc(const uint32_t dex_pc)
+ const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Find the catch block for the given exception type and dex_pc
+ uint32_t FindCatchBlock(Class* exception_type, uint32_t dex_pc) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static void SetClasses(Class* java_lang_reflect_Constructor, Class* java_lang_reflect_Method);
+
+ static Class* GetConstructorClass() {
+ return java_lang_reflect_Constructor_;
+ }
+
+ static Class* GetMethodClass() {
+ return java_lang_reflect_Method_;
+ }
+
+ static void ResetClasses();
+
+ protected:
+ // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
+ // The class we are a part of
+ Class* declaring_class_;
+
+ // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
+ ObjectArray<StaticStorageBase>* dex_cache_initialized_static_storage_;
+
+ // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
+ ObjectArray<AbstractMethod>* dex_cache_resolved_methods_;
+
+ // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
+ ObjectArray<Class>* dex_cache_resolved_types_;
+
+ // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
+ ObjectArray<String>* dex_cache_strings_;
+
+ // Access flags; low 16 bits are defined by spec.
+ uint32_t access_flags_;
+
+ // Compiled code associated with this method for callers from managed code.
+ // May be compiled managed code or a bridge for invoking a native method.
+ const void* code_;
+
+ // Offset to the CodeItem.
+ uint32_t code_item_offset_;
+
+ // Architecture-dependent register spill mask
+ uint32_t core_spill_mask_;
+
+ // Architecture-dependent register spill mask
+ uint32_t fp_spill_mask_;
+
+ // Total size in bytes of the frame
+ size_t frame_size_in_bytes_;
+
+ // Garbage collection map of native PC offsets to reference bitmaps.
+ const uint8_t* native_gc_map_;
+
+ // Native invocation stub entry point for calling from native to managed code.
+ InvokeStub* invoke_stub_;
+
+ // Mapping from native pc to dex pc
+ const uint32_t* mapping_table_;
+
+ // Index into method_ids of the dex file associated with this method
+ uint32_t method_dex_index_;
+
+ // For concrete virtual methods, this is the offset of the method in Class::vtable_.
+ //
+ // For abstract methods in an interface class, this is the offset of the method in
+ // "iftable_->Get(n)->GetMethodArray()".
+ //
+ // For static and direct methods this is the index in the direct methods table.
+ uint32_t method_index_;
+
+ // The target native method registered with this method
+ const void* native_method_;
+
+ // When a register is promoted into a register, the spill mask holds which registers hold dex
+ // registers. The first promoted register's corresponding dex register is vmap_table_[1], the Nth
+ // is vmap_table_[N]. vmap_table_[0] holds the length of the table.
+ const uint16_t* vmap_table_;
+
+ static Class* java_lang_reflect_Constructor_;
+ static Class* java_lang_reflect_Method_;
+
+ friend struct art::AbstractMethodOffsets; // for verifying offset information
+ friend struct art::ConstructorMethodOffsets; // for verifying offset information
+ friend struct art::MethodOffsets; // for verifying offset information
+ DISALLOW_IMPLICIT_CONSTRUCTORS(AbstractMethod);
+};
+
+class MANAGED Method : public AbstractMethod {
+
+};
+
+class MANAGED Constructor : public AbstractMethod {
+
+};
+
+class MANAGED AbstractMethodClass : public Class {
+ private:
+ Object* ORDER_BY_SIGNATURE_;
+ friend struct art::MethodClassOffsets; // for verifying offset information
+ DISALLOW_IMPLICIT_CONSTRUCTORS(AbstractMethodClass);
+};
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_METHOD_H_
diff --git a/src/mirror/array-inl.h b/src/mirror/array-inl.h
new file mode 100644
index 0000000..b7f212f
--- /dev/null
+++ b/src/mirror/array-inl.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_ARRAY_INL_H_
+#define ART_SRC_MIRROR_ARRAY_INL_H_
+
+#include "array.h"
+
+#include "class.h"
+
+namespace art {
+namespace mirror {
+
+inline size_t Array::SizeOf() const {
+ // This is safe from overflow because the array was already allocated, so we know it's sane.
+ size_t component_size = GetClass()->GetComponentSize();
+ int32_t component_count = GetLength();
+ size_t header_size = sizeof(Object) + (component_size == sizeof(int64_t) ? 8 : 4);
+ size_t data_size = component_count * component_size;
+ return header_size + data_size;
+}
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_ARRAY_INL_H_
diff --git a/src/mirror/array.cc b/src/mirror/array.cc
new file mode 100644
index 0000000..103efa3
--- /dev/null
+++ b/src/mirror/array.cc
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "array.h"
+
+#include "class.h"
+#include "class-inl.h"
+#include "gc/card_table-inl.h"
+#include "object-inl.h"
+#include "object_array.h"
+#include "object_array-inl.h"
+#include "object_utils.h"
+#include "sirt_ref.h"
+#include "thread.h"
+#include "utils.h"
+
+namespace art {
+namespace mirror {
+
+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());
+
+ size_t header_size = sizeof(Object) + (component_size == sizeof(int64_t) ? 8 : 4);
+ size_t data_size = component_count * component_size;
+ size_t size = header_size + data_size;
+
+ // 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) {
+ 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(self, array_class, size));
+ if (array != NULL) {
+ DCHECK(array->IsArrayInstance());
+ array->SetLength(component_count);
+ }
+ return array;
+}
+
+Array* Array::Alloc(Thread* self, Class* array_class, int32_t component_count) {
+ DCHECK(array_class->IsArrayClass());
+ return Alloc(self, array_class, component_count, array_class->GetComponentSize());
+}
+
+// Create a multi-dimensional array of Objects or primitive types.
+//
+// We have to generate the names for X[], X[][], X[][][], and so on. The
+// easiest way to deal with that is to create the full name once and then
+// subtract pieces off. Besides, we want to start with the outermost
+// piece and work our way in.
+// Recursively create an array with multiple dimensions. Elements may be
+// Objects or primitive types.
+static Array* RecursiveCreateMultiArray(Thread* self, Class* array_class, int current_dimension,
+ IntArray* dimensions)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ int32_t array_length = dimensions->Get(current_dimension);
+ SirtRef<Array> new_array(self, Array::Alloc(self, array_class, array_length));
+ if (UNLIKELY(new_array.get() == NULL)) {
+ CHECK(self->IsExceptionPending());
+ return NULL;
+ }
+ if ((current_dimension + 1) < dimensions->GetLength()) {
+ // Create a new sub-array in every element of the array.
+ for (int32_t i = 0; i < array_length; i++) {
+ Array* sub_array = RecursiveCreateMultiArray(self, array_class->GetComponentType(),
+ current_dimension + 1, dimensions);
+ if (UNLIKELY(sub_array == NULL)) {
+ CHECK(self->IsExceptionPending());
+ return NULL;
+ }
+ new_array->AsObjectArray<Array>()->Set(i, sub_array);
+ }
+ }
+ return new_array.get();
+}
+
+Array* Array::CreateMultiArray(Thread* self, Class* element_class, IntArray* dimensions) {
+ // Verify dimensions.
+ //
+ // The caller is responsible for verifying that "dimArray" is non-null
+ // and has a length > 0 and <= 255.
+ int num_dimensions = dimensions->GetLength();
+ DCHECK_GT(num_dimensions, 0);
+ DCHECK_LE(num_dimensions, 255);
+
+ for (int i = 0; i < num_dimensions; i++) {
+ int dimension = dimensions->Get(i);
+ if (UNLIKELY(dimension < 0)) {
+ self->ThrowNewExceptionF("Ljava/lang/NegativeArraySizeException;",
+ "Dimension %d: %d", i, dimension);
+ return NULL;
+ }
+ }
+
+ // Generate the full name of the array class.
+ std::string descriptor(num_dimensions, '[');
+ descriptor += ClassHelper(element_class).GetDescriptor();
+
+ // Find/generate the array class.
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ Class* array_class = class_linker->FindClass(descriptor.c_str(), element_class->GetClassLoader());
+ if (UNLIKELY(array_class == NULL)) {
+ CHECK(self->IsExceptionPending());
+ return NULL;
+ }
+ // create the array
+ Array* new_array = RecursiveCreateMultiArray(self, array_class, 0, dimensions);
+ if (UNLIKELY(new_array == NULL)) {
+ CHECK(self->IsExceptionPending());
+ return NULL;
+ }
+ return new_array;
+}
+
+bool Array::ThrowArrayIndexOutOfBoundsException(int32_t index) const {
+ Thread::Current()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
+ "length=%i; index=%i", length_, index);
+ return false;
+}
+
+bool Array::ThrowArrayStoreException(Object* object) const {
+ Thread::Current()->ThrowNewExceptionF("Ljava/lang/ArrayStoreException;",
+ "%s cannot be stored in an array of type %s",
+ PrettyTypeOf(object).c_str(), PrettyTypeOf(this).c_str());
+ return false;
+}
+
+template<typename T>
+PrimitiveArray<T>* PrimitiveArray<T>::Alloc(Thread* self, size_t length) {
+ DCHECK(array_class_ != NULL);
+ Array* raw_array = Array::Alloc(self, array_class_, length, sizeof(T));
+ return down_cast<PrimitiveArray<T>*>(raw_array);
+}
+
+template <typename T> Class* PrimitiveArray<T>::array_class_ = NULL;
+
+// Explicitly instantiate all the primitive array types.
+template class PrimitiveArray<uint8_t>; // BooleanArray
+template class PrimitiveArray<int8_t>; // ByteArray
+template class PrimitiveArray<uint16_t>; // CharArray
+template class PrimitiveArray<double>; // DoubleArray
+template class PrimitiveArray<float>; // FloatArray
+template class PrimitiveArray<int32_t>; // IntArray
+template class PrimitiveArray<int64_t>; // LongArray
+template class PrimitiveArray<int16_t>; // ShortArray
+
+} // namespace mirror
+} // namespace art
diff --git a/src/mirror/array.h b/src/mirror/array.h
new file mode 100644
index 0000000..8da906f
--- /dev/null
+++ b/src/mirror/array.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_ARRAY_H_
+#define ART_SRC_MIRROR_ARRAY_H_
+
+#include "object.h"
+
+namespace art {
+namespace mirror {
+
+class MANAGED Array : public Object {
+ 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(Thread* self, Class* array_class, int32_t component_count)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static Array* Alloc(Thread* self, Class* array_class, int32_t component_count,
+ size_t component_size)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static Array* CreateMultiArray(Thread* self, Class* element_class, IntArray* dimensions)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ size_t SizeOf() const;
+
+ int32_t GetLength() const {
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Array, length_), false);
+ }
+
+ void SetLength(int32_t length) {
+ CHECK_GE(length, 0);
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Array, length_), length, false);
+ }
+
+ static MemberOffset LengthOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(Array, length_);
+ }
+
+ static MemberOffset DataOffset(size_t component_size) {
+ if (component_size != sizeof(int64_t)) {
+ return OFFSET_OF_OBJECT_MEMBER(Array, first_element_);
+ } else {
+ // Align longs and doubles.
+ return MemberOffset(OFFSETOF_MEMBER(Array, first_element_) + 4);
+ }
+ }
+
+ void* GetRawData(size_t component_size) {
+ intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(component_size).Int32Value();
+ return reinterpret_cast<void*>(data);
+ }
+
+ const void* GetRawData(size_t component_size) const {
+ intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(component_size).Int32Value();
+ return reinterpret_cast<const void*>(data);
+ }
+
+ protected:
+ bool IsValidIndex(int32_t index) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ if (UNLIKELY(index < 0 || index >= GetLength())) {
+ return ThrowArrayIndexOutOfBoundsException(index);
+ }
+ return true;
+ }
+
+ protected:
+ bool ThrowArrayIndexOutOfBoundsException(int32_t index) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool ThrowArrayStoreException(Object* object) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ private:
+ // The number of array elements.
+ int32_t length_;
+ // Marker for the data (used by generated code)
+ uint32_t first_element_[0];
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Array);
+};
+
+template<class T>
+class MANAGED PrimitiveArray : public Array {
+ public:
+ typedef T ElementType;
+
+ static PrimitiveArray<T>* Alloc(Thread* self, size_t length)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ const T* GetData() const {
+ intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(sizeof(T)).Int32Value();
+ return reinterpret_cast<T*>(data);
+ }
+
+ T* GetData() {
+ intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(sizeof(T)).Int32Value();
+ return reinterpret_cast<T*>(data);
+ }
+
+ T Get(int32_t i) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ if (!IsValidIndex(i)) {
+ return T(0);
+ }
+ return GetData()[i];
+ }
+
+ void Set(int32_t i, T value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ if (IsValidIndex(i)) {
+ GetData()[i] = value;
+ }
+ }
+
+ static void SetArrayClass(Class* array_class) {
+ CHECK(array_class_ == NULL);
+ CHECK(array_class != NULL);
+ array_class_ = array_class;
+ }
+
+ static void ResetArrayClass() {
+ CHECK(array_class_ != NULL);
+ array_class_ = NULL;
+ }
+
+ private:
+ static Class* array_class_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(PrimitiveArray);
+};
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_ARRAY_H_
diff --git a/src/mirror/class-inl.h b/src/mirror/class-inl.h
new file mode 100644
index 0000000..7eb8601
--- /dev/null
+++ b/src/mirror/class-inl.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_CLASS_INL_H_
+#define ART_SRC_MIRROR_CLASS_INL_H_
+
+#include "class.h"
+
+#include "abstract_method.h"
+#include "field.h"
+#include "iftable.h"
+#include "object_array.h"
+#include "runtime.h"
+#include "string.h"
+
+namespace art {
+namespace mirror {
+
+inline size_t Class::GetObjectSize() const {
+ CHECK(!IsVariableSize()) << " class=" << PrettyTypeOf(this);
+ DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
+ size_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(Class, object_size_), false);
+ CHECK_GE(result, sizeof(Object)) << " class=" << PrettyTypeOf(this);
+ return result;
+}
+
+inline Class* Class::GetSuperClass() const {
+ // Can only get super class for loaded classes (hack for when runtime is
+ // initializing)
+ DCHECK(IsLoaded() || !Runtime::Current()->IsStarted()) << IsLoaded();
+ return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_), false);
+}
+
+inline ObjectArray<AbstractMethod>* Class::GetDirectMethods() const {
+ DCHECK(IsLoaded() || IsErroneous());
+ return GetFieldObject<ObjectArray<AbstractMethod>*>(
+ OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), false);
+}
+
+inline void Class::SetDirectMethods(ObjectArray<AbstractMethod>* new_direct_methods)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(NULL == GetFieldObject<ObjectArray<AbstractMethod>*>(
+ OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), false));
+ DCHECK_NE(0, new_direct_methods->GetLength());
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_),
+ new_direct_methods, false);
+}
+
+inline AbstractMethod* Class::GetDirectMethod(int32_t i) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return GetDirectMethods()->Get(i);
+}
+
+inline void Class::SetDirectMethod(uint32_t i, AbstractMethod* f) // TODO: uint16_t
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){
+ ObjectArray<AbstractMethod>* direct_methods =
+ GetFieldObject<ObjectArray<AbstractMethod>*>(
+ OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), false);
+ direct_methods->Set(i, f);
+}
+
+// Returns the number of static, private, and constructor methods.
+inline size_t Class::NumDirectMethods() const {
+ return (GetDirectMethods() != NULL) ? GetDirectMethods()->GetLength() : 0;
+}
+
+inline ObjectArray<AbstractMethod>* Class::GetVirtualMethods() const {
+ DCHECK(IsLoaded() || IsErroneous());
+ return GetFieldObject<ObjectArray<AbstractMethod>*>(
+ OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_), false);
+}
+
+inline void Class::SetVirtualMethods(ObjectArray<AbstractMethod>* new_virtual_methods) {
+ // TODO: we reassign virtual methods to grow the table for miranda
+ // methods.. they should really just be assigned once
+ DCHECK_NE(0, new_virtual_methods->GetLength());
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_),
+ new_virtual_methods, false);
+}
+
+inline size_t Class::NumVirtualMethods() const {
+ return (GetVirtualMethods() != NULL) ? GetVirtualMethods()->GetLength() : 0;
+}
+
+inline AbstractMethod* Class::GetVirtualMethod(uint32_t i) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(IsResolved() || IsErroneous());
+ return GetVirtualMethods()->Get(i);
+}
+
+inline AbstractMethod* Class::GetVirtualMethodDuringLinking(uint32_t i) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(IsLoaded() || IsErroneous());
+ return GetVirtualMethods()->Get(i);
+}
+
+inline void Class::SetVirtualMethod(uint32_t i, AbstractMethod* f) // TODO: uint16_t
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ ObjectArray<AbstractMethod>* virtual_methods =
+ GetFieldObject<ObjectArray<AbstractMethod>*>(
+ OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_), false);
+ virtual_methods->Set(i, f);
+}
+
+inline ObjectArray<AbstractMethod>* Class::GetVTable() const {
+ DCHECK(IsResolved() || IsErroneous());
+ return GetFieldObject<ObjectArray<AbstractMethod>*>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), false);
+}
+
+inline ObjectArray<AbstractMethod>* Class::GetVTableDuringLinking() const {
+ DCHECK(IsLoaded() || IsErroneous());
+ return GetFieldObject<ObjectArray<AbstractMethod>*>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), false);
+}
+
+inline void Class::SetVTable(ObjectArray<AbstractMethod>* new_vtable)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), new_vtable, false);
+}
+
+inline AbstractMethod* Class::FindVirtualMethodForVirtual(AbstractMethod* method) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(!method->GetDeclaringClass()->IsInterface());
+ // The argument method may from a super class.
+ // Use the index to a potentially overridden one for this instance's class.
+ return GetVTable()->Get(method->GetMethodIndex());
+}
+
+inline AbstractMethod* Class::FindVirtualMethodForSuper(AbstractMethod* method) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(!method->GetDeclaringClass()->IsInterface());
+ return GetSuperClass()->GetVTable()->Get(method->GetMethodIndex());
+}
+
+inline AbstractMethod* Class::FindVirtualMethodForVirtualOrInterface(AbstractMethod* method) const {
+ if (method->IsDirect()) {
+ return method;
+ }
+ if (method->GetDeclaringClass()->IsInterface()) {
+ return FindVirtualMethodForInterface(method);
+ }
+ return FindVirtualMethodForVirtual(method);
+}
+
+inline IfTable* Class::GetIfTable() const {
+ return GetFieldObject<IfTable*>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), false);
+}
+
+inline int32_t Class::GetIfTableCount() const {
+ IfTable* iftable = GetIfTable();
+ if (iftable == NULL) {
+ return 0;
+ }
+ return iftable->Count();
+}
+
+inline void Class::SetIfTable(IfTable* new_iftable) {
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), new_iftable, false);
+}
+
+inline ObjectArray<Field>* Class::GetIFields() const {
+ DCHECK(IsLoaded() || IsErroneous());
+ return GetFieldObject<ObjectArray<Field>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), false);
+}
+
+inline void Class::SetIFields(ObjectArray<Field>* new_ifields)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(NULL == GetFieldObject<ObjectArray<Field>*>(
+ OFFSET_OF_OBJECT_MEMBER(Class, ifields_), false));
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields, false);
+}
+
+inline ObjectArray<Field>* Class::GetSFields() const {
+ DCHECK(IsLoaded() || IsErroneous());
+ return GetFieldObject<ObjectArray<Field>*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), false);
+}
+
+inline void Class::SetSFields(ObjectArray<Field>* new_sfields)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(NULL == GetFieldObject<ObjectArray<Field>*>(
+ OFFSET_OF_OBJECT_MEMBER(Class, sfields_), false));
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields, false);
+}
+
+inline size_t Class::NumStaticFields() const {
+ return (GetSFields() != NULL) ? GetSFields()->GetLength() : 0;
+}
+
+inline Field* Class::GetStaticField(uint32_t i) const // TODO: uint16_t
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return GetSFields()->Get(i);
+}
+
+inline void Class::SetStaticField(uint32_t i, Field* f) // TODO: uint16_t
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ ObjectArray<Field>* sfields= GetFieldObject<ObjectArray<Field>*>(
+ OFFSET_OF_OBJECT_MEMBER(Class, sfields_), false);
+ sfields->Set(i, f);
+}
+
+inline size_t Class::NumInstanceFields() const {
+ return (GetIFields() != NULL) ? GetIFields()->GetLength() : 0;
+}
+
+inline Field* Class::GetInstanceField(uint32_t i) const // TODO: uint16_t
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){
+ DCHECK_NE(NumInstanceFields(), 0U);
+ return GetIFields()->Get(i);
+}
+
+inline void Class::SetInstanceField(uint32_t i, Field* f) // TODO: uint16_t
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){
+ ObjectArray<Field>* ifields= GetFieldObject<ObjectArray<Field>*>(
+ OFFSET_OF_OBJECT_MEMBER(Class, ifields_), false);
+ ifields->Set(i, f);
+}
+
+inline void Class::SetVerifyErrorClass(Class* klass) {
+ CHECK(klass != NULL) << PrettyClass(this);
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), klass, false);
+}
+
+inline uint32_t Class::GetAccessFlags() const {
+ // Check class is loaded or this is java.lang.String that has a
+ // circularity issue during loading the names of its members
+ DCHECK(IsLoaded() || IsErroneous() ||
+ this == String::GetJavaLangString() ||
+ this == Field::GetJavaLangReflectField() ||
+ this == AbstractMethod::GetConstructorClass() ||
+ this == AbstractMethod::GetMethodClass());
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), false);
+}
+
+inline String* Class::GetName() const {
+ return GetFieldObject<String*>(OFFSET_OF_OBJECT_MEMBER(Class, name_), false);
+}
+inline void Class::SetName(String* name) {
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, name_), name, false);
+}
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_CLASS_INL_H_
diff --git a/src/mirror/class.cc b/src/mirror/class.cc
new file mode 100644
index 0000000..7f52d17
--- /dev/null
+++ b/src/mirror/class.cc
@@ -0,0 +1,668 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "class.h"
+
+#include "abstract_method-inl.h"
+#include "class-inl.h"
+#include "class_linker.h"
+#include "class_loader.h"
+#include "dex_cache.h"
+#include "field-inl.h"
+#include "gc/card_table-inl.h"
+#include "object-inl.h"
+#include "object_array-inl.h"
+#include "object_utils.h"
+#include "runtime.h"
+#include "sirt_ref.h"
+#include "thread.h"
+#include "throwable.h"
+#include "utils.h"
+#include "well_known_classes.h"
+
+namespace art {
+namespace mirror {
+
+Class* Class::java_lang_Class_ = NULL;
+
+void Class::SetClassClass(Class* java_lang_Class) {
+ CHECK(java_lang_Class_ == NULL) << java_lang_Class_ << " " << java_lang_Class;
+ CHECK(java_lang_Class != NULL);
+ java_lang_Class_ = java_lang_Class;
+}
+
+void Class::ResetClass() {
+ CHECK(java_lang_Class_ != NULL);
+ java_lang_Class_ = NULL;
+}
+
+void Class::SetStatus(Status new_status) {
+ CHECK(new_status > GetStatus() || new_status == kStatusError || !Runtime::Current()->IsStarted())
+ << PrettyClass(this) << " " << GetStatus() << " -> " << new_status;
+ CHECK(sizeof(Status) == sizeof(uint32_t)) << PrettyClass(this);
+ if (new_status > kStatusResolved) {
+ CHECK_EQ(GetThinLockId(), Thread::Current()->GetThinLockId()) << PrettyClass(this);
+ }
+ if (new_status == kStatusError) {
+ CHECK_NE(GetStatus(), kStatusError) << PrettyClass(this);
+
+ // stash current exception
+ Thread* self = Thread::Current();
+ SirtRef<Throwable> exception(self, self->GetException());
+ CHECK(exception.get() != NULL);
+
+ // clear exception to call FindSystemClass
+ self->ClearException();
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ Class* eiie_class = class_linker->FindSystemClass("Ljava/lang/ExceptionInInitializerError;");
+ CHECK(!self->IsExceptionPending());
+
+ // only verification errors, not initialization problems, should set a verify error.
+ // this is to ensure that ThrowEarlierClassFailure will throw NoClassDefFoundError in that case.
+ Class* exception_class = exception->GetClass();
+ if (!eiie_class->IsAssignableFrom(exception_class)) {
+ SetVerifyErrorClass(exception_class);
+ }
+
+ // restore exception
+ self->SetException(exception.get());
+ }
+ return SetField32(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status, false);
+}
+
+DexCache* Class::GetDexCache() const {
+ return GetFieldObject<DexCache*>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), false);
+}
+
+void Class::SetDexCache(DexCache* new_dex_cache) {
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache, false);
+}
+
+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(self, this, this->object_size_);
+}
+
+void Class::SetClassSize(size_t new_class_size) {
+ DCHECK_GE(new_class_size, GetClassSize()) << " class=" << PrettyTypeOf(this);
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), new_class_size, false);
+}
+
+// Return the class' name. The exact format is bizarre, but it's the specified behavior for
+// Class.getName: keywords for primitive types, regular "[I" form for primitive arrays (so "int"
+// but "[I"), and arrays of reference types written between "L" and ";" but with dots rather than
+// slashes (so "java.lang.String" but "[Ljava.lang.String;"). Madness.
+String* Class::ComputeName() {
+ String* name = GetName();
+ if (name != NULL) {
+ return name;
+ }
+ std::string descriptor(ClassHelper(this).GetDescriptor());
+ if ((descriptor[0] != 'L') && (descriptor[0] != '[')) {
+ // The descriptor indicates that this is the class for
+ // a primitive type; special-case the return value.
+ const char* c_name = NULL;
+ switch (descriptor[0]) {
+ case 'Z': c_name = "boolean"; break;
+ case 'B': c_name = "byte"; break;
+ case 'C': c_name = "char"; break;
+ case 'S': c_name = "short"; break;
+ case 'I': c_name = "int"; break;
+ case 'J': c_name = "long"; break;
+ case 'F': c_name = "float"; break;
+ case 'D': c_name = "double"; break;
+ case 'V': c_name = "void"; break;
+ default:
+ LOG(FATAL) << "Unknown primitive type: " << PrintableChar(descriptor[0]);
+ }
+ 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.
+ if (descriptor.size() > 2 && descriptor[0] == 'L' && descriptor[descriptor.size() - 1] == ';') {
+ descriptor.erase(0, 1);
+ descriptor.erase(descriptor.size() - 1);
+ }
+ std::replace(descriptor.begin(), descriptor.end(), '/', '.');
+ name = String::AllocFromModifiedUtf8(Thread::Current(), descriptor.c_str());
+ }
+ SetName(name);
+ return name;
+}
+
+void Class::DumpClass(std::ostream& os, int flags) const {
+ if ((flags & kDumpClassFullDetail) == 0) {
+ os << PrettyClass(this);
+ if ((flags & kDumpClassClassLoader) != 0) {
+ os << ' ' << GetClassLoader();
+ }
+ if ((flags & kDumpClassInitialized) != 0) {
+ os << ' ' << GetStatus();
+ }
+ os << "\n";
+ return;
+ }
+
+ Class* super = GetSuperClass();
+ ClassHelper kh(this);
+ os << "----- " << (IsInterface() ? "interface" : "class") << " "
+ << "'" << kh.GetDescriptor() << "' cl=" << GetClassLoader() << " -----\n",
+ os << " objectSize=" << SizeOf() << " "
+ << "(" << (super != NULL ? super->SizeOf() : -1) << " from super)\n",
+ os << StringPrintf(" access=0x%04x.%04x\n",
+ GetAccessFlags() >> 16, GetAccessFlags() & kAccJavaFlagsMask);
+ if (super != NULL) {
+ os << " super='" << PrettyClass(super) << "' (cl=" << super->GetClassLoader() << ")\n";
+ }
+ if (IsArrayClass()) {
+ os << " componentType=" << PrettyClass(GetComponentType()) << "\n";
+ }
+ if (kh.NumDirectInterfaces() > 0) {
+ os << " interfaces (" << kh.NumDirectInterfaces() << "):\n";
+ for (size_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
+ Class* interface = kh.GetDirectInterface(i);
+ const ClassLoader* cl = interface->GetClassLoader();
+ os << StringPrintf(" %2zd: %s (cl=%p)\n", i, PrettyClass(interface).c_str(), cl);
+ }
+ }
+ os << " vtable (" << NumVirtualMethods() << " entries, "
+ << (super != NULL ? super->NumVirtualMethods() : 0) << " in super):\n";
+ for (size_t i = 0; i < NumVirtualMethods(); ++i) {
+ os << StringPrintf(" %2zd: %s\n", i, PrettyMethod(GetVirtualMethodDuringLinking(i)).c_str());
+ }
+ os << " direct methods (" << NumDirectMethods() << " entries):\n";
+ for (size_t i = 0; i < NumDirectMethods(); ++i) {
+ os << StringPrintf(" %2zd: %s\n", i, PrettyMethod(GetDirectMethod(i)).c_str());
+ }
+ if (NumStaticFields() > 0) {
+ os << " static fields (" << NumStaticFields() << " entries):\n";
+ if (IsResolved() || IsErroneous()) {
+ for (size_t i = 0; i < NumStaticFields(); ++i) {
+ os << StringPrintf(" %2zd: %s\n", i, PrettyField(GetStaticField(i)).c_str());
+ }
+ } else {
+ os << " <not yet available>";
+ }
+ }
+ if (NumInstanceFields() > 0) {
+ os << " instance fields (" << NumInstanceFields() << " entries):\n";
+ if (IsResolved() || IsErroneous()) {
+ for (size_t i = 0; i < NumInstanceFields(); ++i) {
+ os << StringPrintf(" %2zd: %s\n", i, PrettyField(GetInstanceField(i)).c_str());
+ }
+ } else {
+ os << " <not yet available>";
+ }
+ }
+}
+
+void Class::SetReferenceInstanceOffsets(uint32_t new_reference_offsets) {
+ if (new_reference_offsets != CLASS_WALK_SUPER) {
+ // Sanity check that the number of bits set in the reference offset bitmap
+ // agrees with the number of references
+ size_t count = 0;
+ for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
+ count += c->NumReferenceInstanceFieldsDuringLinking();
+ }
+ CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets), count);
+ }
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_),
+ new_reference_offsets, false);
+}
+
+void Class::SetReferenceStaticOffsets(uint32_t new_reference_offsets) {
+ if (new_reference_offsets != CLASS_WALK_SUPER) {
+ // Sanity check that the number of bits set in the reference offset bitmap
+ // agrees with the number of references
+ CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets),
+ NumReferenceStaticFieldsDuringLinking());
+ }
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_static_offsets_),
+ new_reference_offsets, false);
+}
+
+bool Class::Implements(const Class* klass) const {
+ DCHECK(klass != NULL);
+ DCHECK(klass->IsInterface()) << PrettyClass(this);
+ // All interfaces implemented directly and by our superclass, and
+ // recursively all super-interfaces of those interfaces, are listed
+ // in iftable_, so we can just do a linear scan through that.
+ int32_t iftable_count = GetIfTableCount();
+ IfTable* iftable = GetIfTable();
+ for (int32_t i = 0; i < iftable_count; i++) {
+ if (iftable->GetInterface(i) == klass) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Determine whether "this" is assignable from "src", where both of these
+// are array classes.
+//
+// Consider an array class, e.g. Y[][], where Y is a subclass of X.
+// Y[][] = Y[][] --> true (identity)
+// X[][] = Y[][] --> true (element superclass)
+// Y = Y[][] --> false
+// Y[] = Y[][] --> false
+// Object = Y[][] --> true (everything is an object)
+// Object[] = Y[][] --> true
+// Object[][] = Y[][] --> true
+// Object[][][] = Y[][] --> false (too many []s)
+// Serializable = Y[][] --> true (all arrays are Serializable)
+// Serializable[] = Y[][] --> true
+// Serializable[][] = Y[][] --> false (unless Y is Serializable)
+//
+// Don't forget about primitive types.
+// Object[] = int[] --> false
+//
+bool Class::IsArrayAssignableFromArray(const Class* src) const {
+ DCHECK(IsArrayClass()) << PrettyClass(this);
+ DCHECK(src->IsArrayClass()) << PrettyClass(src);
+ return GetComponentType()->IsAssignableFrom(src->GetComponentType());
+}
+
+bool Class::IsAssignableFromArray(const Class* src) const {
+ DCHECK(!IsInterface()) << PrettyClass(this); // handled first in IsAssignableFrom
+ DCHECK(src->IsArrayClass()) << PrettyClass(src);
+ if (!IsArrayClass()) {
+ // If "this" is not also an array, it must be Object.
+ // src's super should be java_lang_Object, since it is an array.
+ Class* java_lang_Object = src->GetSuperClass();
+ DCHECK(java_lang_Object != NULL) << PrettyClass(src);
+ DCHECK(java_lang_Object->GetSuperClass() == NULL) << PrettyClass(src);
+ return this == java_lang_Object;
+ }
+ return IsArrayAssignableFromArray(src);
+}
+
+bool Class::IsSubClass(const Class* klass) const {
+ DCHECK(!IsInterface()) << PrettyClass(this);
+ DCHECK(!IsArrayClass()) << PrettyClass(this);
+ const Class* current = this;
+ do {
+ if (current == klass) {
+ return true;
+ }
+ current = current->GetSuperClass();
+ } while (current != NULL);
+ return false;
+}
+
+bool Class::IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2) {
+ size_t i = 0;
+ while (descriptor1[i] != '\0' && descriptor1[i] == descriptor2[i]) {
+ ++i;
+ }
+ if (descriptor1.find('/', i) != StringPiece::npos ||
+ descriptor2.find('/', i) != StringPiece::npos) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+bool Class::IsInSamePackage(const Class* that) const {
+ const Class* klass1 = this;
+ const Class* klass2 = that;
+ if (klass1 == klass2) {
+ return true;
+ }
+ // Class loaders must match.
+ if (klass1->GetClassLoader() != klass2->GetClassLoader()) {
+ return false;
+ }
+ // Arrays are in the same package when their element classes are.
+ while (klass1->IsArrayClass()) {
+ klass1 = klass1->GetComponentType();
+ }
+ while (klass2->IsArrayClass()) {
+ klass2 = klass2->GetComponentType();
+ }
+ // Compare the package part of the descriptor string.
+ ClassHelper kh(klass1);
+ std::string descriptor1(kh.GetDescriptor());
+ kh.ChangeClass(klass2);
+ std::string descriptor2(kh.GetDescriptor());
+ return IsInSamePackage(descriptor1, descriptor2);
+}
+
+bool Class::IsClassClass() const {
+ Class* java_lang_Class = GetClass()->GetClass();
+ return this == java_lang_Class;
+}
+
+bool Class::IsStringClass() const {
+ return this == String::GetJavaLangString();
+}
+
+bool Class::IsThrowableClass() const {
+ return WellKnownClasses::ToClass(WellKnownClasses::java_lang_Throwable)->IsAssignableFrom(this);
+}
+
+bool Class::IsFieldClass() const {
+ Class* java_lang_Class = GetClass();
+ Class* java_lang_reflect_Field = java_lang_Class->GetInstanceField(0)->GetClass();
+ return this == java_lang_reflect_Field;
+
+}
+
+bool Class::IsMethodClass() const {
+ return (this == AbstractMethod::GetMethodClass()) ||
+ (this == AbstractMethod::GetConstructorClass());
+
+}
+
+ClassLoader* Class::GetClassLoader() const {
+ return GetFieldObject<ClassLoader*>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), false);
+}
+
+void Class::SetClassLoader(ClassLoader* new_class_loader) {
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader, false);
+}
+
+AbstractMethod* Class::FindVirtualMethodForInterface(AbstractMethod* method) const {
+ Class* declaring_class = method->GetDeclaringClass();
+ DCHECK(declaring_class != NULL) << PrettyClass(this);
+ DCHECK(declaring_class->IsInterface()) << PrettyMethod(method);
+ // TODO cache to improve lookup speed
+ int32_t iftable_count = GetIfTableCount();
+ IfTable* iftable = GetIfTable();
+ for (int32_t i = 0; i < iftable_count; i++) {
+ if (iftable->GetInterface(i) == declaring_class) {
+ return iftable->GetMethodArray(i)->Get(method->GetMethodIndex());
+ }
+ }
+ return NULL;
+}
+
+AbstractMethod* Class::FindInterfaceMethod(const StringPiece& name, const StringPiece& signature) const {
+ // Check the current class before checking the interfaces.
+ AbstractMethod* method = FindDeclaredVirtualMethod(name, signature);
+ if (method != NULL) {
+ return method;
+ }
+
+ int32_t iftable_count = GetIfTableCount();
+ IfTable* iftable = GetIfTable();
+ for (int32_t i = 0; i < iftable_count; i++) {
+ method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(name, signature);
+ if (method != NULL) {
+ return method;
+ }
+ }
+ return NULL;
+}
+
+AbstractMethod* Class::FindInterfaceMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const {
+ // Check the current class before checking the interfaces.
+ AbstractMethod* method = FindDeclaredVirtualMethod(dex_cache, dex_method_idx);
+ if (method != NULL) {
+ return method;
+ }
+
+ int32_t iftable_count = GetIfTableCount();
+ IfTable* iftable = GetIfTable();
+ for (int32_t i = 0; i < iftable_count; i++) {
+ method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(dex_cache, dex_method_idx);
+ if (method != NULL) {
+ return method;
+ }
+ }
+ return NULL;
+}
+
+
+AbstractMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const StringPiece& signature) const {
+ MethodHelper mh;
+ for (size_t i = 0; i < NumDirectMethods(); ++i) {
+ AbstractMethod* method = GetDirectMethod(i);
+ mh.ChangeMethod(method);
+ if (name == mh.GetName() && signature == mh.GetSignature()) {
+ return method;
+ }
+ }
+ return NULL;
+}
+
+AbstractMethod* Class::FindDeclaredDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const {
+ if (GetDexCache() == dex_cache) {
+ for (size_t i = 0; i < NumDirectMethods(); ++i) {
+ AbstractMethod* method = GetDirectMethod(i);
+ if (method->GetDexMethodIndex() == dex_method_idx) {
+ return method;
+ }
+ }
+ }
+ return NULL;
+}
+
+AbstractMethod* Class::FindDirectMethod(const StringPiece& name, const StringPiece& signature) const {
+ for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
+ AbstractMethod* method = klass->FindDeclaredDirectMethod(name, signature);
+ if (method != NULL) {
+ return method;
+ }
+ }
+ return NULL;
+}
+
+AbstractMethod* Class::FindDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const {
+ for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
+ AbstractMethod* method = klass->FindDeclaredDirectMethod(dex_cache, dex_method_idx);
+ if (method != NULL) {
+ return method;
+ }
+ }
+ return NULL;
+}
+
+AbstractMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name,
+ const StringPiece& signature) const {
+ MethodHelper mh;
+ for (size_t i = 0; i < NumVirtualMethods(); ++i) {
+ AbstractMethod* method = GetVirtualMethod(i);
+ mh.ChangeMethod(method);
+ if (name == mh.GetName() && signature == mh.GetSignature()) {
+ return method;
+ }
+ }
+ return NULL;
+}
+
+AbstractMethod* Class::FindDeclaredVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const {
+ if (GetDexCache() == dex_cache) {
+ for (size_t i = 0; i < NumVirtualMethods(); ++i) {
+ AbstractMethod* method = GetVirtualMethod(i);
+ if (method->GetDexMethodIndex() == dex_method_idx) {
+ return method;
+ }
+ }
+ }
+ return NULL;
+}
+
+AbstractMethod* Class::FindVirtualMethod(const StringPiece& name, const StringPiece& signature) const {
+ for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
+ AbstractMethod* method = klass->FindDeclaredVirtualMethod(name, signature);
+ if (method != NULL) {
+ return method;
+ }
+ }
+ return NULL;
+}
+
+AbstractMethod* Class::FindVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const {
+ for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
+ AbstractMethod* method = klass->FindDeclaredVirtualMethod(dex_cache, dex_method_idx);
+ if (method != NULL) {
+ return method;
+ }
+ }
+ return NULL;
+}
+
+Field* Class::FindDeclaredInstanceField(const StringPiece& name, const StringPiece& type) {
+ // Is the field in this class?
+ // Interfaces are not relevant because they can't contain instance fields.
+ FieldHelper fh;
+ for (size_t i = 0; i < NumInstanceFields(); ++i) {
+ Field* f = GetInstanceField(i);
+ fh.ChangeField(f);
+ if (name == fh.GetName() && type == fh.GetTypeDescriptor()) {
+ return f;
+ }
+ }
+ return NULL;
+}
+
+Field* Class::FindDeclaredInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx) {
+ if (GetDexCache() == dex_cache) {
+ for (size_t i = 0; i < NumInstanceFields(); ++i) {
+ Field* f = GetInstanceField(i);
+ if (f->GetDexFieldIndex() == dex_field_idx) {
+ return f;
+ }
+ }
+ }
+ return NULL;
+}
+
+Field* Class::FindInstanceField(const StringPiece& name, const StringPiece& type) {
+ // Is the field in this class, or any of its superclasses?
+ // Interfaces are not relevant because they can't contain instance fields.
+ for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
+ Field* f = c->FindDeclaredInstanceField(name, type);
+ if (f != NULL) {
+ return f;
+ }
+ }
+ return NULL;
+}
+
+Field* Class::FindInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx) {
+ // Is the field in this class, or any of its superclasses?
+ // Interfaces are not relevant because they can't contain instance fields.
+ for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
+ Field* f = c->FindDeclaredInstanceField(dex_cache, dex_field_idx);
+ if (f != NULL) {
+ return f;
+ }
+ }
+ return NULL;
+}
+
+Field* Class::FindDeclaredStaticField(const StringPiece& name, const StringPiece& type) {
+ DCHECK(type != NULL);
+ FieldHelper fh;
+ for (size_t i = 0; i < NumStaticFields(); ++i) {
+ Field* f = GetStaticField(i);
+ fh.ChangeField(f);
+ if (name == fh.GetName() && type == fh.GetTypeDescriptor()) {
+ return f;
+ }
+ }
+ return NULL;
+}
+
+Field* Class::FindDeclaredStaticField(const DexCache* dex_cache, uint32_t dex_field_idx) {
+ if (dex_cache == GetDexCache()) {
+ for (size_t i = 0; i < NumStaticFields(); ++i) {
+ Field* f = GetStaticField(i);
+ if (f->GetDexFieldIndex() == dex_field_idx) {
+ return f;
+ }
+ }
+ }
+ return NULL;
+}
+
+Field* Class::FindStaticField(const StringPiece& name, const StringPiece& type) {
+ // Is the field in this class (or its interfaces), or any of its
+ // superclasses (or their interfaces)?
+ ClassHelper kh;
+ for (Class* k = this; k != NULL; k = k->GetSuperClass()) {
+ // Is the field in this class?
+ Field* f = k->FindDeclaredStaticField(name, type);
+ if (f != NULL) {
+ return f;
+ }
+ // Is this field in any of this class' interfaces?
+ kh.ChangeClass(k);
+ for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
+ Class* interface = kh.GetDirectInterface(i);
+ f = interface->FindStaticField(name, type);
+ if (f != NULL) {
+ return f;
+ }
+ }
+ }
+ return NULL;
+}
+
+Field* Class::FindStaticField(const DexCache* dex_cache, uint32_t dex_field_idx) {
+ ClassHelper kh;
+ for (Class* k = this; k != NULL; k = k->GetSuperClass()) {
+ // Is the field in this class?
+ Field* f = k->FindDeclaredStaticField(dex_cache, dex_field_idx);
+ if (f != NULL) {
+ return f;
+ }
+ // Is this field in any of this class' interfaces?
+ kh.ChangeClass(k);
+ for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
+ Class* interface = kh.GetDirectInterface(i);
+ f = interface->FindStaticField(dex_cache, dex_field_idx);
+ if (f != NULL) {
+ return f;
+ }
+ }
+ }
+ return NULL;
+}
+
+Field* Class::FindField(const StringPiece& name, const StringPiece& type) {
+ // Find a field using the JLS field resolution order
+ ClassHelper kh;
+ for (Class* k = this; k != NULL; k = k->GetSuperClass()) {
+ // Is the field in this class?
+ Field* f = k->FindDeclaredInstanceField(name, type);
+ if (f != NULL) {
+ return f;
+ }
+ f = k->FindDeclaredStaticField(name, type);
+ if (f != NULL) {
+ return f;
+ }
+ // Is this field in any of this class' interfaces?
+ kh.ChangeClass(k);
+ for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
+ Class* interface = kh.GetDirectInterface(i);
+ f = interface->FindStaticField(name, type);
+ if (f != NULL) {
+ return f;
+ }
+ }
+ }
+ return NULL;
+}
+
+} // namespace mirror
+} // namespace art
diff --git a/src/mirror/class.h b/src/mirror/class.h
new file mode 100644
index 0000000..843e07c
--- /dev/null
+++ b/src/mirror/class.h
@@ -0,0 +1,866 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_CLASS_H_
+#define ART_SRC_MIRROR_CLASS_H_
+
+#include "modifiers.h"
+#include "object.h"
+#include "primitive.h"
+
+/*
+ * A magic value for refOffsets. Ignore the bits and walk the super
+ * chain when this is the value.
+ * [This is an unlikely "natural" value, since it would be 30 non-ref instance
+ * fields followed by 2 ref instance fields.]
+ */
+#define CLASS_WALK_SUPER ((unsigned int)(3))
+#define CLASS_BITS_PER_WORD (sizeof(unsigned long int) * 8)
+#define CLASS_OFFSET_ALIGNMENT 4
+#define CLASS_HIGH_BIT ((unsigned int)1 << (CLASS_BITS_PER_WORD - 1))
+/*
+ * Given an offset, return the bit number which would encode that offset.
+ * Local use only.
+ */
+#define _CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset) \
+ ((unsigned int)(byteOffset) / \
+ CLASS_OFFSET_ALIGNMENT)
+/*
+ * Is the given offset too large to be encoded?
+ */
+#define CLASS_CAN_ENCODE_OFFSET(byteOffset) \
+ (_CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset) < CLASS_BITS_PER_WORD)
+/*
+ * Return a single bit, encoding the offset.
+ * Undefined if the offset is too large, as defined above.
+ */
+#define CLASS_BIT_FROM_OFFSET(byteOffset) \
+ (CLASS_HIGH_BIT >> _CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset))
+/*
+ * Return an offset, given a bit number as returned from CLZ.
+ */
+#define CLASS_OFFSET_FROM_CLZ(rshift) \
+ MemberOffset((static_cast<int>(rshift) * CLASS_OFFSET_ALIGNMENT))
+
+namespace art {
+
+struct ClassClassOffsets;
+struct ClassOffsets;
+class StringPiece;
+
+namespace mirror {
+
+class ClassLoader;
+class DexCache;
+class Field;
+class IfTable;
+
+// Type for the InitializedStaticStorage table. Currently the Class
+// provides the static storage. However, this might change to an Array
+// to improve image sharing, so we use this type to avoid assumptions
+// on the current storage.
+class MANAGED StaticStorageBase : public Object {
+};
+
+// C++ mirror of java.lang.Class
+class MANAGED Class : public StaticStorageBase {
+ public:
+ // Class Status
+ //
+ // kStatusNotReady: If a Class cannot be found in the class table by
+ // FindClass, it allocates an new one with AllocClass in the
+ // kStatusNotReady and calls LoadClass. Note if it does find a
+ // class, it may not be kStatusResolved and it will try to push it
+ // forward toward kStatusResolved.
+ //
+ // kStatusIdx: LoadClass populates with Class with information from
+ // the DexFile, moving the status to kStatusIdx, indicating that the
+ // Class value in super_class_ has not been populated. The new Class
+ // can then be inserted into the classes table.
+ //
+ // kStatusLoaded: After taking a lock on Class, the ClassLinker will
+ // attempt to move a kStatusIdx class forward to kStatusLoaded by
+ // using ResolveClass to initialize the super_class_ and ensuring the
+ // interfaces are resolved.
+ //
+ // kStatusResolved: Still holding the lock on Class, the ClassLinker
+ // shows linking is complete and fields of the Class populated by making
+ // it kStatusResolved. Java allows circularities of the form where a super
+ // class has a field that is of the type of the sub class. We need to be able
+ // to fully resolve super classes while resolving types for fields.
+ //
+ // kStatusRetryVerificationAtRuntime: The verifier sets a class to
+ // this state if it encounters a soft failure at compile time. This
+ // often happens when there are unresolved classes in other dex
+ // files, and this status marks a class as needing to be verified
+ // again at runtime.
+ //
+ // TODO: Explain the other states
+ enum Status {
+ kStatusError = -1,
+ kStatusNotReady = 0,
+ kStatusIdx = 1, // Loaded, DEX idx in super_class_type_idx_ and interfaces_type_idx_.
+ kStatusLoaded = 2, // DEX idx values resolved.
+ kStatusResolved = 3, // Part of linking.
+ kStatusVerifying = 4, // In the process of being verified.
+ kStatusRetryVerificationAtRuntime = 5, // Compile time verification failed, retry at runtime.
+ kStatusVerifyingAtRuntime = 6, // Retrying verification at runtime.
+ kStatusVerified = 7, // Logically part of linking; done pre-init.
+ kStatusInitializing = 8, // Class init in progress.
+ kStatusInitialized = 9, // Ready to go.
+ };
+
+ Status GetStatus() const {
+ DCHECK_EQ(sizeof(Status), sizeof(uint32_t));
+ return static_cast<Status>(GetField32(OFFSET_OF_OBJECT_MEMBER(Class, status_), false));
+ }
+
+ void SetStatus(Status new_status) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Returns true if the class has failed to link.
+ bool IsErroneous() const {
+ return GetStatus() == kStatusError;
+ }
+
+ // Returns true if the class has been loaded.
+ bool IsIdxLoaded() const {
+ return GetStatus() >= kStatusIdx;
+ }
+
+ // Returns true if the class has been loaded.
+ bool IsLoaded() const {
+ return GetStatus() >= kStatusLoaded;
+ }
+
+ // Returns true if the class has been linked.
+ bool IsResolved() const {
+ return GetStatus() >= kStatusResolved;
+ }
+
+ // Returns true if the class was compile-time verified.
+ bool IsCompileTimeVerified() const {
+ return GetStatus() >= kStatusRetryVerificationAtRuntime;
+ }
+
+ // Returns true if the class has been verified.
+ bool IsVerified() const {
+ return GetStatus() >= kStatusVerified;
+ }
+
+ // Returns true if the class is initializing.
+ bool IsInitializing() const {
+ return GetStatus() >= kStatusInitializing;
+ }
+
+ // Returns true if the class is initialized.
+ bool IsInitialized() const {
+ return GetStatus() == kStatusInitialized;
+ }
+
+ uint32_t GetAccessFlags() const;
+
+ void SetAccessFlags(uint32_t new_access_flags) {
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), new_access_flags, false);
+ }
+
+ // Returns true if the class is an interface.
+ bool IsInterface() const {
+ return (GetAccessFlags() & kAccInterface) != 0;
+ }
+
+ // Returns true if the class is declared public.
+ bool IsPublic() const {
+ return (GetAccessFlags() & kAccPublic) != 0;
+ }
+
+ // Returns true if the class is declared final.
+ bool IsFinal() const {
+ return (GetAccessFlags() & kAccFinal) != 0;
+ }
+
+ bool IsFinalizable() const {
+ return (GetAccessFlags() & kAccClassIsFinalizable) != 0;
+ }
+
+ void SetFinalizable() {
+ uint32_t flags = GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), false);
+ SetAccessFlags(flags | kAccClassIsFinalizable);
+ }
+
+ // Returns true if the class is abstract.
+ bool IsAbstract() const {
+ return (GetAccessFlags() & kAccAbstract) != 0;
+ }
+
+ // Returns true if the class is an annotation.
+ bool IsAnnotation() const {
+ return (GetAccessFlags() & kAccAnnotation) != 0;
+ }
+
+ // Returns true if the class is synthetic.
+ bool IsSynthetic() const {
+ return (GetAccessFlags() & kAccSynthetic) != 0;
+ }
+
+ bool IsReferenceClass() const {
+ return (GetAccessFlags() & kAccClassIsReference) != 0;
+ }
+
+ bool IsWeakReferenceClass() const {
+ return (GetAccessFlags() & kAccClassIsWeakReference) != 0;
+ }
+
+ bool IsSoftReferenceClass() const {
+ return (GetAccessFlags() & kAccReferenceFlagsMask) == kAccClassIsReference;
+ }
+
+ bool IsFinalizerReferenceClass() const {
+ return (GetAccessFlags() & kAccClassIsFinalizerReference) != 0;
+ }
+
+ bool IsPhantomReferenceClass() const {
+ return (GetAccessFlags() & kAccClassIsPhantomReference) != 0;
+ }
+
+
+ String* GetName() const; // Returns the cached name.
+ void SetName(String* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Sets the cached name.
+ // Computes the name, then sets the cached value.
+ String* ComputeName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ bool IsProxyClass() const {
+ // Read access flags without using getter as whether something is a proxy can be check in
+ // any loaded state
+ // TODO: switch to a check if the super class is java.lang.reflect.Proxy?
+ uint32_t access_flags = GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), false);
+ return (access_flags & kAccClassIsProxy) != 0;
+ }
+
+ Primitive::Type GetPrimitiveType() const {
+ DCHECK_EQ(sizeof(Primitive::Type), sizeof(int32_t));
+ return static_cast<Primitive::Type>(
+ GetField32(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_), false));
+ }
+
+ void SetPrimitiveType(Primitive::Type new_type) {
+ DCHECK_EQ(sizeof(Primitive::Type), sizeof(int32_t));
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_), new_type, false);
+ }
+
+ // Returns true if the class is a primitive type.
+ bool IsPrimitive() const {
+ return GetPrimitiveType() != Primitive::kPrimNot;
+ }
+
+ bool IsPrimitiveBoolean() const {
+ return GetPrimitiveType() == Primitive::kPrimBoolean;
+ }
+
+ bool IsPrimitiveByte() const {
+ return GetPrimitiveType() == Primitive::kPrimByte;
+ }
+
+ bool IsPrimitiveChar() const {
+ return GetPrimitiveType() == Primitive::kPrimChar;
+ }
+
+ bool IsPrimitiveShort() const {
+ return GetPrimitiveType() == Primitive::kPrimShort;
+ }
+
+ bool IsPrimitiveInt() const {
+ return GetPrimitiveType() == Primitive::kPrimInt;
+ }
+
+ bool IsPrimitiveLong() const {
+ return GetPrimitiveType() == Primitive::kPrimLong;
+ }
+
+ bool IsPrimitiveFloat() const {
+ return GetPrimitiveType() == Primitive::kPrimFloat;
+ }
+
+ bool IsPrimitiveDouble() const {
+ return GetPrimitiveType() == Primitive::kPrimDouble;
+ }
+
+ bool IsPrimitiveVoid() const {
+ return GetPrimitiveType() == Primitive::kPrimVoid;
+ }
+
+ bool IsPrimitiveArray() const {
+ return IsArrayClass() && GetComponentType()->IsPrimitive();
+ }
+
+ // Depth of class from java.lang.Object
+ size_t Depth() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ size_t depth = 0;
+ for (Class* klass = this; klass->GetSuperClass() != NULL; klass = klass->GetSuperClass()) {
+ depth++;
+ }
+ return depth;
+ }
+
+ bool IsArrayClass() const {
+ return GetComponentType() != NULL;
+ }
+
+ bool IsClassClass() const;
+
+ bool IsStringClass() const;
+
+ bool IsThrowableClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ bool IsFieldClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ bool IsMethodClass() const;
+
+ Class* GetComponentType() const {
+ return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Class, component_type_), false);
+ }
+
+ void SetComponentType(Class* new_component_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(GetComponentType() == NULL);
+ DCHECK(new_component_type != NULL);
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, component_type_), new_component_type, false);
+ }
+
+ size_t GetComponentSize() const {
+ return Primitive::ComponentSize(GetComponentType()->GetPrimitiveType());
+ }
+
+ bool IsObjectClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return !IsPrimitive() && GetSuperClass() == NULL;
+ }
+ bool IsInstantiable() const {
+ return !IsPrimitive() && !IsInterface() && !IsAbstract();
+ }
+
+ bool IsObjectArrayClass() const {
+ return GetComponentType() != NULL && !GetComponentType()->IsPrimitive();
+ }
+
+ // Creates a raw object instance but does not invoke the default constructor.
+ 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
+ // be used to get their instance size
+ return IsClassClass() || IsArrayClass();
+ }
+
+ size_t SizeOf() const {
+ DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), false);
+ }
+
+ size_t GetClassSize() const {
+ DCHECK_EQ(sizeof(size_t), sizeof(uint32_t));
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), false);
+ }
+
+ void SetClassSize(size_t new_class_size)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ size_t GetObjectSize() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void SetObjectSize(size_t new_object_size) {
+ DCHECK(!IsVariableSize());
+ DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
+ return SetField32(OFFSET_OF_OBJECT_MEMBER(Class, object_size_), new_object_size, false);
+ }
+
+ // Returns true if this class is in the same packages as that class.
+ bool IsInSamePackage(const Class* that) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static bool IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2);
+
+ // Returns true if this class can access that class.
+ bool CanAccess(Class* that) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return that->IsPublic() || this->IsInSamePackage(that);
+ }
+
+ // Can this class access a member in the provided class with the provided member access flags?
+ // Note that access to the class isn't checked in case the declaring class is protected and the
+ // method has been exposed by a public sub-class
+ bool CanAccessMember(Class* access_to, uint32_t member_flags) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ // Classes can access all of their own members
+ if (this == access_to) {
+ return true;
+ }
+ // Public members are trivially accessible
+ if (member_flags & kAccPublic) {
+ return true;
+ }
+ // Private members are trivially not accessible
+ if (member_flags & kAccPrivate) {
+ return false;
+ }
+ // Check for protected access from a sub-class, which may or may not be in the same package.
+ if (member_flags & kAccProtected) {
+ if (this->IsSubClass(access_to)) {
+ return true;
+ }
+ }
+ // Allow protected access from other classes in the same package.
+ return this->IsInSamePackage(access_to);
+ }
+
+ bool IsSubClass(const Class* klass) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Can src be assigned to this class? For example, String can be assigned to Object (by an
+ // upcast), however, an Object cannot be assigned to a String as a potentially exception throwing
+ // downcast would be necessary. Similarly for interfaces, a class that implements (or an interface
+ // that extends) another can be assigned to its parent, but not vice-versa. All Classes may assign
+ // to themselves. Classes for primitive types may not assign to each other.
+ bool IsAssignableFrom(const Class* src) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(src != NULL);
+ if (this == src) {
+ // Can always assign to things of the same type.
+ return true;
+ } else if (IsObjectClass()) {
+ // Can assign any reference to java.lang.Object.
+ return !src->IsPrimitive();
+ } else if (IsInterface()) {
+ return src->Implements(this);
+ } else if (src->IsArrayClass()) {
+ return IsAssignableFromArray(src);
+ } else {
+ return !src->IsInterface() && src->IsSubClass(this);
+ }
+ }
+
+ Class* GetSuperClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void SetSuperClass(Class *new_super_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ // super class is assigned once, except during class linker initialization
+ Class* old_super_class = GetFieldObject<Class*>(
+ OFFSET_OF_OBJECT_MEMBER(Class, super_class_), false);
+ DCHECK(old_super_class == NULL || old_super_class == new_super_class);
+ DCHECK(new_super_class != NULL);
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, super_class_), new_super_class, false);
+ }
+
+ bool HasSuperClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return GetSuperClass() != NULL;
+ }
+
+ static MemberOffset SuperClassOffset() {
+ return MemberOffset(OFFSETOF_MEMBER(Class, super_class_));
+ }
+
+ ClassLoader* GetClassLoader() const;
+
+ void SetClassLoader(ClassLoader* new_cl) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static MemberOffset DexCacheOffset() {
+ return MemberOffset(OFFSETOF_MEMBER(Class, dex_cache_));
+ }
+
+ enum {
+ kDumpClassFullDetail = 1,
+ kDumpClassClassLoader = (1 << 1),
+ kDumpClassInitialized = (1 << 2),
+ };
+
+ void DumpClass(std::ostream& os, int flags) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ DexCache* GetDexCache() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void SetDexCache(DexCache* new_dex_cache) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ ObjectArray<AbstractMethod>* GetDirectMethods() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void SetDirectMethods(ObjectArray<AbstractMethod>* new_direct_methods)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ AbstractMethod* GetDirectMethod(int32_t i) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void SetDirectMethod(uint32_t i, AbstractMethod* f) // TODO: uint16_t
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Returns the number of static, private, and constructor methods.
+ size_t NumDirectMethods() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ ObjectArray<AbstractMethod>* GetVirtualMethods() const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void SetVirtualMethods(ObjectArray<AbstractMethod>* new_virtual_methods)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Returns the number of non-inherited virtual methods.
+ size_t NumVirtualMethods() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ AbstractMethod* GetVirtualMethod(uint32_t i) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ AbstractMethod* GetVirtualMethodDuringLinking(uint32_t i) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void SetVirtualMethod(uint32_t i, AbstractMethod* f) // TODO: uint16_t
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ ObjectArray<AbstractMethod>* GetVTable() const;
+
+ ObjectArray<AbstractMethod>* GetVTableDuringLinking() const;
+
+ void SetVTable(ObjectArray<AbstractMethod>* new_vtable)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static MemberOffset VTableOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(Class, vtable_);
+ }
+
+ // Given a method implemented by this class but potentially from a super class, return the
+ // specific implementation method for this class.
+ AbstractMethod* FindVirtualMethodForVirtual(AbstractMethod* method) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Given a method implemented by this class' super class, return the specific implementation
+ // method for this class.
+ AbstractMethod* FindVirtualMethodForSuper(AbstractMethod* method) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Given a method implemented by this class, but potentially from a
+ // super class or interface, return the specific implementation
+ // method for this class.
+ AbstractMethod* FindVirtualMethodForInterface(AbstractMethod* method) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ AbstractMethod* FindInterfaceMethod(const StringPiece& name, const StringPiece& descriptor) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ AbstractMethod* FindInterfaceMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ AbstractMethod* FindVirtualMethodForVirtualOrInterface(AbstractMethod* method) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ AbstractMethod* FindDeclaredVirtualMethod(const StringPiece& name, const StringPiece& signature) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ AbstractMethod* FindDeclaredVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ AbstractMethod* FindVirtualMethod(const StringPiece& name, const StringPiece& descriptor) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ AbstractMethod* FindVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ AbstractMethod* FindDeclaredDirectMethod(const StringPiece& name, const StringPiece& signature) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ AbstractMethod* FindDeclaredDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ AbstractMethod* FindDirectMethod(const StringPiece& name, const StringPiece& signature) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ AbstractMethod* FindDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ int32_t GetIfTableCount() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ IfTable* GetIfTable() const;
+
+ void SetIfTable(IfTable* new_iftable) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Get instance fields of the class (See also GetSFields).
+ ObjectArray<Field>* GetIFields() const;
+
+ void SetIFields(ObjectArray<Field>* new_ifields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ size_t NumInstanceFields() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ Field* GetInstanceField(uint32_t i) const // TODO: uint16_t
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void SetInstanceField(uint32_t i, Field* f) // TODO: uint16_t
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Returns the number of instance fields containing reference types.
+ size_t NumReferenceInstanceFields() const {
+ DCHECK(IsResolved() || IsErroneous());
+ DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_instance_fields_), false);
+ }
+
+ size_t NumReferenceInstanceFieldsDuringLinking() const {
+ DCHECK(IsLoaded() || IsErroneous());
+ DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_instance_fields_), false);
+ }
+
+ void SetNumReferenceInstanceFields(size_t new_num) {
+ DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_instance_fields_), new_num, false);
+ }
+
+ uint32_t GetReferenceInstanceOffsets() const {
+ DCHECK(IsResolved() || IsErroneous());
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_), false);
+ }
+
+ void SetReferenceInstanceOffsets(uint32_t new_reference_offsets)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Beginning of static field data
+ static MemberOffset FieldsOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(Class, fields_);
+ }
+
+ // Returns the number of static fields containing reference types.
+ size_t NumReferenceStaticFields() const {
+ DCHECK(IsResolved() || IsErroneous());
+ DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_static_fields_), false);
+ }
+
+ size_t NumReferenceStaticFieldsDuringLinking() const {
+ DCHECK(IsLoaded() || IsErroneous());
+ DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_static_fields_), false);
+ }
+
+ void SetNumReferenceStaticFields(size_t new_num) {
+ DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_static_fields_), new_num, false);
+ }
+
+ // Gets the static fields of the class.
+ ObjectArray<Field>* GetSFields() const;
+
+ void SetSFields(ObjectArray<Field>* new_sfields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ size_t NumStaticFields() const;
+
+ Field* GetStaticField(uint32_t i) const; // TODO: uint16_t
+
+ void SetStaticField(uint32_t i, Field* f); // TODO: uint16_t
+
+ uint32_t GetReferenceStaticOffsets() const {
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_static_offsets_), false);
+ }
+
+ void SetReferenceStaticOffsets(uint32_t new_reference_offsets);
+
+ // Find a static or instance field using the JLS resolution order
+ Field* FindField(const StringPiece& name, const StringPiece& type)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Finds the given instance field in this class or a superclass.
+ Field* FindInstanceField(const StringPiece& name, const StringPiece& type)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Finds the given instance field in this class or a superclass, only searches classes that
+ // have the same dex cache.
+ Field* FindInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ Field* FindDeclaredInstanceField(const StringPiece& name, const StringPiece& type)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ Field* FindDeclaredInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Finds the given static field in this class or a superclass.
+ Field* FindStaticField(const StringPiece& name, const StringPiece& type)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Finds the given static field in this class or superclass, only searches classes that
+ // have the same dex cache.
+ Field* FindStaticField(const DexCache* dex_cache, uint32_t dex_field_idx)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ Field* FindDeclaredStaticField(const StringPiece& name, const StringPiece& type)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ Field* FindDeclaredStaticField(const DexCache* dex_cache, uint32_t dex_field_idx)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ pid_t GetClinitThreadId() const {
+ DCHECK(IsIdxLoaded() || IsErroneous());
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), false);
+ }
+
+ void SetClinitThreadId(pid_t new_clinit_thread_id) {
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id, false);
+ }
+
+ Class* GetVerifyErrorClass() const {
+ // DCHECK(IsErroneous());
+ return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), false);
+ }
+
+ uint16_t GetDexTypeIndex() const {
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_), false);
+ }
+
+ void SetDexTypeIndex(uint16_t type_idx) {
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_), type_idx, false);
+ }
+
+ static Class* GetJavaLangClass() {
+ DCHECK(java_lang_Class_ != NULL);
+ return java_lang_Class_;
+ }
+
+ // Can't call this SetClass or else gets called instead of Object::SetClass in places.
+ static void SetClassClass(Class* java_lang_Class);
+ static void ResetClass();
+
+ private:
+ void SetVerifyErrorClass(Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ bool Implements(const Class* klass) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool IsArrayAssignableFromArray(const Class* klass) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool IsAssignableFromArray(const Class* klass) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // defining class loader, or NULL for the "bootstrap" system loader
+ ClassLoader* class_loader_;
+
+ // For array classes, the component class object for instanceof/checkcast
+ // (for String[][][], this will be String[][]). NULL for non-array classes.
+ Class* component_type_;
+
+ // DexCache of resolved constant pool entries (will be NULL for classes generated by the
+ // runtime such as arrays and primitive classes).
+ DexCache* dex_cache_;
+
+ // static, private, and <init> methods
+ ObjectArray<AbstractMethod>* direct_methods_;
+
+ // instance fields
+ //
+ // These describe the layout of the contents of an Object.
+ // Note that only the fields directly declared by this class are
+ // listed in ifields; fields declared by a superclass are listed in
+ // the superclass's Class.ifields.
+ //
+ // All instance fields that refer to objects are guaranteed to be at
+ // the beginning of the field list. num_reference_instance_fields_
+ // specifies the number of reference fields.
+ ObjectArray<Field>* ifields_;
+
+ // The interface table (iftable_) contains pairs of a interface class and an array of the
+ // interface methods. There is one pair per interface supported by this class. That means one
+ // pair for each interface we support directly, indirectly via superclass, or indirectly via a
+ // superinterface. This will be null if neither we nor our superclass implement any interfaces.
+ //
+ // Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()".
+ // Invoke faceObj.blah(), where "blah" is part of the Face interface. We can't easily use a
+ // single vtable.
+ //
+ // For every interface a concrete class implements, we create an array of the concrete vtable_
+ // methods for the methods in the interface.
+ IfTable* iftable_;
+
+ // descriptor for the class such as "java.lang.Class" or "[C". Lazily initialized by ComputeName
+ String* name_;
+
+ // Static fields
+ ObjectArray<Field>* sfields_;
+
+ // The superclass, or NULL if this is java.lang.Object, an interface or primitive type.
+ Class* super_class_;
+
+ // If class verify fails, we must return same error on subsequent tries.
+ Class* verify_error_class_;
+
+ // virtual methods defined in this class; invoked through vtable
+ ObjectArray<AbstractMethod>* virtual_methods_;
+
+ // Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass is
+ // copied in, and virtual methods from our class either replace those from the super or are
+ // appended. For abstract classes, methods may be created in the vtable that aren't in
+ // virtual_ methods_ for miranda methods.
+ ObjectArray<AbstractMethod>* vtable_;
+
+ // access flags; low 16 bits are defined by VM spec
+ uint32_t access_flags_;
+
+ // Total size of the Class instance; used when allocating storage on gc heap.
+ // See also object_size_.
+ size_t class_size_;
+
+ // tid used to check for recursive <clinit> invocation
+ pid_t clinit_thread_id_;
+
+ // type index from dex file
+ // TODO: really 16bits
+ uint32_t dex_type_idx_;
+
+ // number of instance fields that are object refs
+ size_t num_reference_instance_fields_;
+
+ // number of static fields that are object refs
+ size_t num_reference_static_fields_;
+
+ // Total object size; used when allocating storage on gc heap.
+ // (For interfaces and abstract classes this will be zero.)
+ // See also class_size_.
+ size_t object_size_;
+
+ // primitive type value, or Primitive::kPrimNot (0); set for generated prim classes
+ Primitive::Type primitive_type_;
+
+ // Bitmap of offsets of ifields.
+ uint32_t reference_instance_offsets_;
+
+ // Bitmap of offsets of sfields.
+ uint32_t reference_static_offsets_;
+
+ // state of class initialization
+ Status status_;
+
+ // TODO: ?
+ // initiating class loader list
+ // NOTE: for classes with low serialNumber, these are unused, and the
+ // values are kept in a table in gDvm.
+ // InitiatingLoaderList initiating_loader_list_;
+
+ // Location of first static field.
+ uint32_t fields_[0];
+
+ // java.lang.Class
+ static Class* java_lang_Class_;
+
+ friend struct art::ClassOffsets; // for verifying offset information
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Class);
+};
+
+std::ostream& operator<<(std::ostream& os, const Class::Status& rhs);
+
+class MANAGED ClassClass : public Class {
+ private:
+ int32_t padding_;
+ int64_t serialVersionUID_;
+ friend struct art::ClassClassOffsets; // for verifying offset information
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ClassClass);
+};
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_CLASS_H_
diff --git a/src/class_loader.h b/src/mirror/class_loader.h
similarity index 85%
rename from src/class_loader.h
rename to src/mirror/class_loader.h
index 029c4a2..0d635f1 100644
--- a/src/class_loader.h
+++ b/src/mirror/class_loader.h
@@ -20,10 +20,14 @@
#include <vector>
#include "dex_file.h"
-#include "object.h"
+#include "mirror/object.h"
namespace art {
+struct ClassLoaderOffsets;
+
+namespace mirror {
+
// C++ mirror of java.lang.ClassLoader
class MANAGED ClassLoader : public Object {
private:
@@ -32,10 +36,11 @@
ClassLoader* parent_;
Object* proxyCache_;
- friend struct ClassLoaderOffsets; // for verifying offset information
+ friend struct art::ClassLoaderOffsets; // for verifying offset information
DISALLOW_IMPLICIT_CONSTRUCTORS(ClassLoader);
};
+} // namespace mirror
} // namespace art
#endif // ART_SRC_CLASS_LOADER_H_
diff --git a/src/dex_cache.cc b/src/mirror/dex_cache.cc
similarity index 81%
rename from src/dex_cache.cc
rename to src/mirror/dex_cache.cc
index 98fc932..3009786 100644
--- a/src/dex_cache.cc
+++ b/src/mirror/dex_cache.cc
@@ -14,14 +14,22 @@
* limitations under the License.
*/
+#include "dex_cache.h"
+
+#include "abstract_method-inl.h"
#include "base/logging.h"
#include "class_linker.h"
-#include "dex_cache.h"
#include "heap.h"
+#include "gc/card_table-inl.h"
#include "globals.h"
#include "object.h"
+#include "object-inl.h"
+#include "object_array-inl.h"
+#include "runtime.h"
+#include "string.h"
namespace art {
+namespace mirror {
void DexCache::Init(const DexFile* dex_file,
String* location,
@@ -70,4 +78,17 @@
}
}
+AbstractMethod* DexCache::GetResolvedMethod(uint32_t method_idx) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ AbstractMethod* method = GetResolvedMethods()->Get(method_idx);
+ // Hide resolution trampoline methods from the caller
+ if (method != NULL && method->IsRuntimeMethod()) {
+ DCHECK(method == Runtime::Current()->GetResolutionMethod());
+ return NULL;
+ } else {
+ return method;
+ }
+}
+
+} // namespace mirror
} // namespace art
diff --git a/src/dex_cache.h b/src/mirror/dex_cache.h
similarity index 88%
rename from src/dex_cache.h
rename to src/mirror/dex_cache.h
index ee44856..307588b 100644
--- a/src/dex_cache.h
+++ b/src/mirror/dex_cache.h
@@ -14,22 +14,26 @@
* limitations under the License.
*/
-#ifndef ART_SRC_DEX_CACHE_H_
-#define ART_SRC_DEX_CACHE_H_
+#ifndef ART_SRC_MIRROR_DEX_CACHE_H_
+#define ART_SRC_MIRROR_DEX_CACHE_H_
-#include "base/macros.h"
-#include "dex_file.h"
-#include "globals.h"
+#include "abstract_method.h"
+#include "class.h"
#include "object.h"
+#include "object_array.h"
+#include "string.h"
namespace art {
+struct DexCacheOffsets;
+class DexFile;
+class ImageWriter;
+union JValue;
+
+namespace mirror {
+
class Class;
class Field;
-class ImageWriter;
-class AbstractMethod;
-class String;
-union JValue;
class MANAGED DexCacheClass : public Class {
private:
@@ -107,16 +111,7 @@
}
AbstractMethod* GetResolvedMethod(uint32_t method_idx) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method = GetResolvedMethods()->Get(method_idx);
- // Hide resolution trampoline methods from the caller
- if (method != NULL && method->GetDexMethodIndex() == DexFile::kDexNoIndex16) {
- DCHECK(method == Runtime::Current()->GetResolutionMethod());
- return NULL;
- } else {
- return method;
- }
- }
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void SetResolvedMethod(uint32_t method_idx, AbstractMethod* resolved)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -177,10 +172,11 @@
ObjectArray<String>* strings_;
uint32_t dex_file_;
- friend struct DexCacheOffsets; // for verifying offset information
+ friend struct art::DexCacheOffsets; // for verifying offset information
DISALLOW_IMPLICIT_CONSTRUCTORS(DexCache);
};
+} // namespace mirror
} // namespace art
-#endif // ART_SRC_DEX_CACHE_H_
+#endif // ART_SRC_MIRROR_DEX_CACHE_H_
diff --git a/src/dex_cache_test.cc b/src/mirror/dex_cache_test.cc
similarity index 96%
rename from src/dex_cache_test.cc
rename to src/mirror/dex_cache_test.cc
index b131e4c..9817660 100644
--- a/src/dex_cache_test.cc
+++ b/src/mirror/dex_cache_test.cc
@@ -18,12 +18,13 @@
#include "common_test.h"
#include "dex_cache.h"
#include "heap.h"
-#include "object.h"
+#include "mirror/object_array-inl.h"
#include "sirt_ref.h"
#include <stdio.h>
namespace art {
+namespace mirror {
class DexCacheTest : public CommonTest {};
@@ -57,4 +58,5 @@
static_cast<uint32_t>(dex_cache->GetInitializedStaticStorage()->GetLength()));
}
+} // namespace mirror
} // namespace art
diff --git a/src/mirror/field-inl.h b/src/mirror/field-inl.h
new file mode 100644
index 0000000..b73cf19
--- /dev/null
+++ b/src/mirror/field-inl.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_FIELD_INL_H_
+#define ART_SRC_MIRROR_FIELD_INL_H_
+
+#include "field.h"
+
+namespace art {
+namespace mirror {
+
+inline Class* Field::GetDeclaringClass() const {
+ Class* result = GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Field, declaring_class_), false);
+ DCHECK(result != NULL);
+ DCHECK(result->IsLoaded() || result->IsErroneous());
+ return result;
+}
+
+inline void Field::SetDeclaringClass(Class *new_declaring_class) {
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Field, declaring_class_), new_declaring_class, false);
+}
+
+inline uint32_t Field::GetAccessFlags() const {
+ DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Field, access_flags_), false);
+}
+
+inline MemberOffset Field::GetOffset() const {
+ DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous());
+ return MemberOffset(GetField32(OFFSET_OF_OBJECT_MEMBER(Field, offset_), false));
+}
+
+inline MemberOffset Field::GetOffsetDuringLinking() const {
+ DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
+ return MemberOffset(GetField32(OFFSET_OF_OBJECT_MEMBER(Field, offset_), false));
+}
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_FIELD_INL_H_
diff --git a/src/mirror/field.cc b/src/mirror/field.cc
new file mode 100644
index 0000000..dab7868
--- /dev/null
+++ b/src/mirror/field.cc
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "field.h"
+
+#include "field-inl.h"
+#include "gc/card_table-inl.h"
+#include "object-inl.h"
+#include "object_utils.h"
+#include "runtime.h"
+#include "utils.h"
+
+namespace art {
+namespace mirror {
+
+// TODO: get global references for these
+Class* Field::java_lang_reflect_Field_ = NULL;
+
+void Field::SetClass(Class* java_lang_reflect_Field) {
+ CHECK(java_lang_reflect_Field_ == NULL);
+ CHECK(java_lang_reflect_Field != NULL);
+ java_lang_reflect_Field_ = java_lang_reflect_Field;
+}
+
+void Field::ResetClass() {
+ CHECK(java_lang_reflect_Field_ != NULL);
+ java_lang_reflect_Field_ = NULL;
+}
+
+void Field::SetOffset(MemberOffset num_bytes) {
+ DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
+#if 0 // TODO enable later in boot and under !NDEBUG
+ FieldHelper fh(this);
+ Primitive::Type type = fh.GetTypeAsPrimitiveType();
+ if (type == Primitive::kPrimDouble || type == Primitive::kPrimLong) {
+ DCHECK_ALIGNED(num_bytes.Uint32Value(), 8);
+ }
+#endif
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Field, offset_), num_bytes.Uint32Value(), false);
+}
+
+uint32_t Field::Get32(const Object* object) const {
+ DCHECK(object != NULL) << PrettyField(this);
+ DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
+ return object->GetField32(GetOffset(), IsVolatile());
+}
+
+void Field::Set32(Object* object, uint32_t new_value) const {
+ DCHECK(object != NULL) << PrettyField(this);
+ DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
+ object->SetField32(GetOffset(), new_value, IsVolatile());
+}
+
+uint64_t Field::Get64(const Object* object) const {
+ DCHECK(object != NULL) << PrettyField(this);
+ DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
+ return object->GetField64(GetOffset(), IsVolatile());
+}
+
+void Field::Set64(Object* object, uint64_t new_value) const {
+ DCHECK(object != NULL) << PrettyField(this);
+ DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
+ object->SetField64(GetOffset(), new_value, IsVolatile());
+}
+
+Object* Field::GetObj(const Object* object) const {
+ DCHECK(object != NULL) << PrettyField(this);
+ DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
+ return object->GetFieldObject<Object*>(GetOffset(), IsVolatile());
+}
+
+void Field::SetObj(Object* object, const Object* new_value) const {
+ DCHECK(object != NULL) << PrettyField(this);
+ DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
+ object->SetFieldObject(GetOffset(), new_value, IsVolatile());
+}
+
+bool Field::GetBoolean(const Object* object) const {
+ DCHECK_EQ(Primitive::kPrimBoolean, FieldHelper(this).GetTypeAsPrimitiveType())
+ << PrettyField(this);
+ return Get32(object);
+}
+
+void Field::SetBoolean(Object* object, bool z) const {
+ DCHECK_EQ(Primitive::kPrimBoolean, FieldHelper(this).GetTypeAsPrimitiveType())
+ << PrettyField(this);
+ Set32(object, z);
+}
+
+int8_t Field::GetByte(const Object* object) const {
+ DCHECK_EQ(Primitive::kPrimByte, FieldHelper(this).GetTypeAsPrimitiveType())
+ << PrettyField(this);
+ return Get32(object);
+}
+
+void Field::SetByte(Object* object, int8_t b) const {
+ DCHECK_EQ(Primitive::kPrimByte, FieldHelper(this).GetTypeAsPrimitiveType())
+ << PrettyField(this);
+ Set32(object, b);
+}
+
+uint16_t Field::GetChar(const Object* object) const {
+ DCHECK_EQ(Primitive::kPrimChar, FieldHelper(this).GetTypeAsPrimitiveType())
+ << PrettyField(this);
+ return Get32(object);
+}
+
+void Field::SetChar(Object* object, uint16_t c) const {
+ DCHECK_EQ(Primitive::kPrimChar, FieldHelper(this).GetTypeAsPrimitiveType())
+ << PrettyField(this);
+ Set32(object, c);
+}
+
+int16_t Field::GetShort(const Object* object) const {
+ DCHECK_EQ(Primitive::kPrimShort, FieldHelper(this).GetTypeAsPrimitiveType())
+ << PrettyField(this);
+ return Get32(object);
+}
+
+void Field::SetShort(Object* object, int16_t s) const {
+ DCHECK_EQ(Primitive::kPrimShort, FieldHelper(this).GetTypeAsPrimitiveType())
+ << PrettyField(this);
+ Set32(object, s);
+}
+
+int32_t Field::GetInt(const Object* object) const {
+#ifndef NDEBUG
+ Primitive::Type type = FieldHelper(this).GetTypeAsPrimitiveType();
+ CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
+#endif
+ return Get32(object);
+}
+
+void Field::SetInt(Object* object, int32_t i) const {
+#ifndef NDEBUG
+ Primitive::Type type = FieldHelper(this).GetTypeAsPrimitiveType();
+ CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
+#endif
+ Set32(object, i);
+}
+
+int64_t Field::GetLong(const Object* object) const {
+#ifndef NDEBUG
+ Primitive::Type type = FieldHelper(this).GetTypeAsPrimitiveType();
+ CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
+#endif
+ return Get64(object);
+}
+
+void Field::SetLong(Object* object, int64_t j) const {
+#ifndef NDEBUG
+ Primitive::Type type = FieldHelper(this).GetTypeAsPrimitiveType();
+ CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
+#endif
+ Set64(object, j);
+}
+
+union Bits {
+ jdouble d;
+ jfloat f;
+ jint i;
+ jlong j;
+};
+
+float Field::GetFloat(const Object* object) const {
+ DCHECK_EQ(Primitive::kPrimFloat, FieldHelper(this).GetTypeAsPrimitiveType())
+ << PrettyField(this);
+ Bits bits;
+ bits.i = Get32(object);
+ return bits.f;
+}
+
+void Field::SetFloat(Object* object, float f) const {
+ DCHECK_EQ(Primitive::kPrimFloat, FieldHelper(this).GetTypeAsPrimitiveType())
+ << PrettyField(this);
+ Bits bits;
+ bits.f = f;
+ Set32(object, bits.i);
+}
+
+double Field::GetDouble(const Object* object) const {
+ DCHECK_EQ(Primitive::kPrimDouble, FieldHelper(this).GetTypeAsPrimitiveType())
+ << PrettyField(this);
+ Bits bits;
+ bits.j = Get64(object);
+ return bits.d;
+}
+
+void Field::SetDouble(Object* object, double d) const {
+ DCHECK_EQ(Primitive::kPrimDouble, FieldHelper(this).GetTypeAsPrimitiveType())
+ << PrettyField(this);
+ Bits bits;
+ bits.d = d;
+ Set64(object, bits.j);
+}
+
+Object* Field::GetObject(const Object* object) const {
+ DCHECK_EQ(Primitive::kPrimNot, FieldHelper(this).GetTypeAsPrimitiveType())
+ << PrettyField(this);
+ return GetObj(object);
+}
+
+void Field::SetObject(Object* object, const Object* l) const {
+ DCHECK_EQ(Primitive::kPrimNot, FieldHelper(this).GetTypeAsPrimitiveType())
+ << PrettyField(this);
+ SetObj(object, l);
+}
+
+} // namespace mirror
+} // namespace art
diff --git a/src/mirror/field.h b/src/mirror/field.h
new file mode 100644
index 0000000..4e7abe8
--- /dev/null
+++ b/src/mirror/field.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_FIELD_H_
+#define ART_SRC_MIRROR_FIELD_H_
+
+#include "class.h"
+#include "modifiers.h"
+#include "object.h"
+
+namespace art {
+
+struct FieldClassOffsets;
+struct FieldOffsets;
+
+namespace mirror {
+
+// C++ mirror of java.lang.reflect.Field
+class MANAGED Field : public Object {
+ public:
+ Class* GetDeclaringClass() const;
+
+ void SetDeclaringClass(Class *new_declaring_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ uint32_t GetAccessFlags() const;
+
+ void SetAccessFlags(uint32_t new_access_flags) {
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Field, access_flags_), new_access_flags, false);
+ }
+
+ bool IsPublic() const {
+ return (GetAccessFlags() & kAccPublic) != 0;
+ }
+
+ bool IsStatic() const {
+ return (GetAccessFlags() & kAccStatic) != 0;
+ }
+
+ bool IsFinal() const {
+ return (GetAccessFlags() & kAccFinal) != 0;
+ }
+
+ uint32_t GetDexFieldIndex() const {
+ return GetField32(OFFSET_OF_OBJECT_MEMBER(Field, field_dex_idx_), false);
+ }
+
+ void SetDexFieldIndex(uint32_t new_idx) {
+ SetField32(OFFSET_OF_OBJECT_MEMBER(Field, field_dex_idx_), new_idx, false);
+ }
+
+ // Offset to field within an Object
+ MemberOffset GetOffset() const;
+
+ static MemberOffset OffsetOffset() {
+ return MemberOffset(OFFSETOF_MEMBER(Field, offset_));
+ }
+
+ MemberOffset GetOffsetDuringLinking() const;
+
+ void SetOffset(MemberOffset num_bytes);
+
+ // field access, null object for static fields
+ bool GetBoolean(const Object* object) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetBoolean(Object* object, bool z) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ int8_t GetByte(const Object* object) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetByte(Object* object, int8_t b) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ uint16_t GetChar(const Object* object) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetChar(Object* object, uint16_t c) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ int16_t GetShort(const Object* object) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetShort(Object* object, int16_t s) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ int32_t GetInt(const Object* object) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetInt(Object* object, int32_t i) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ int64_t GetLong(const Object* object) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetLong(Object* object, int64_t j) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ float GetFloat(const Object* object) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetFloat(Object* object, float f) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ double GetDouble(const Object* object) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetDouble(Object* object, double d) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ Object* GetObject(const Object* object) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetObject(Object* object, const Object* l) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // raw field accesses
+ uint32_t Get32(const Object* object) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void Set32(Object* object, uint32_t new_value) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ uint64_t Get64(const Object* object) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void Set64(Object* object, uint64_t new_value) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ Object* GetObj(const Object* object) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ void SetObj(Object* object, const Object* new_value) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static Class* GetJavaLangReflectField() {
+ DCHECK(java_lang_reflect_Field_ != NULL);
+ return java_lang_reflect_Field_;
+ }
+
+ static void SetClass(Class* java_lang_reflect_Field);
+ static void ResetClass();
+
+ bool IsVolatile() const {
+ return (GetAccessFlags() & kAccVolatile) != 0;
+ }
+
+ private:
+ // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
+ // The class we are a part of
+ Class* declaring_class_;
+
+ uint32_t access_flags_;
+
+ // Dex cache index of field id
+ uint32_t field_dex_idx_;
+
+ // Offset of field within an instance or in the Class' static fields
+ uint32_t offset_;
+
+ static Class* java_lang_reflect_Field_;
+
+ friend struct art::FieldOffsets; // for verifying offset information
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Field);
+};
+
+class MANAGED FieldClass : public Class {
+ private:
+ Object* ORDER_BY_NAME_AND_DECLARING_CLASS_;
+ friend struct art::FieldClassOffsets; // for verifying offset information
+ DISALLOW_IMPLICIT_CONSTRUCTORS(FieldClass);
+};
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_FIELD_H_
diff --git a/src/mirror/iftable-inl.h b/src/mirror/iftable-inl.h
new file mode 100644
index 0000000..72803b8
--- /dev/null
+++ b/src/mirror/iftable-inl.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_IFTABLE_INL_H_
+#define ART_SRC_MIRROR_IFTABLE_INL_H_
+
+#include "iftable.h"
+
+namespace art {
+namespace mirror {
+
+inline void IfTable::SetInterface(int32_t i, Class* interface) {
+ DCHECK(interface != NULL);
+ DCHECK(interface->IsInterface());
+ DCHECK(Get((i * kMax) + kInterface) == NULL);
+ Set((i * kMax) + kInterface, interface);
+}
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_IFTABLE_INL_H_
diff --git a/src/mirror/iftable.h b/src/mirror/iftable.h
new file mode 100644
index 0000000..ffb2e51
--- /dev/null
+++ b/src/mirror/iftable.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_IFTABLE_H_
+#define ART_SRC_MIRROR_IFTABLE_H_
+
+#include "object_array.h"
+
+namespace art {
+namespace mirror {
+
+class MANAGED IfTable : public ObjectArray<Object> {
+ public:
+ Class* GetInterface(int32_t i) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ Class* interface = Get((i * kMax) + kInterface)->AsClass();
+ DCHECK(interface != NULL);
+ return interface;
+ }
+
+ void SetInterface(int32_t i, Class* interface) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ ObjectArray<AbstractMethod>* GetMethodArray(int32_t i) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ ObjectArray<AbstractMethod>* method_array =
+ down_cast<ObjectArray<AbstractMethod>*>(Get((i * kMax) + kMethodArray));
+ DCHECK(method_array != NULL);
+ return method_array;
+ }
+
+ size_t GetMethodArrayCount(int32_t i) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ ObjectArray<AbstractMethod>* method_array =
+ down_cast<ObjectArray<AbstractMethod>*>(Get((i * kMax) + kMethodArray));
+ if (method_array == NULL) {
+ return 0;
+ }
+ return method_array->GetLength();
+ }
+
+ void SetMethodArray(int32_t i, ObjectArray<AbstractMethod>* new_ma)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(new_ma != NULL);
+ DCHECK(Get((i * kMax) + kMethodArray) == NULL);
+ Set((i * kMax) + kMethodArray, new_ma);
+ }
+
+ size_t Count() const {
+ return GetLength() / kMax;
+ }
+
+ enum {
+ // Points to the interface class.
+ kInterface = 0,
+ // Method pointers into the vtable, allow fast map from interface method index to concrete
+ // instance method.
+ kMethodArray = 1,
+ kMax = 2,
+ };
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(IfTable);
+};
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_IFTABLE_H_
diff --git a/src/mirror/object-inl.h b/src/mirror/object-inl.h
new file mode 100644
index 0000000..723192d
--- /dev/null
+++ b/src/mirror/object-inl.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_OBJECT_INL_H_
+#define ART_SRC_MIRROR_OBJECT_INL_H_
+
+#include "object.h"
+
+#include "abstract_method.h"
+#include "atomic.h"
+#include "array.h"
+#include "field.h"
+#include "class.h"
+#include "runtime.h"
+
+namespace art {
+namespace mirror {
+
+inline Class* Object::GetClass() const {
+ return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Object, klass_), false);
+}
+
+inline void Object::SetClass(Class* new_klass) {
+ // new_klass may be NULL prior to class linker initialization
+ // We don't mark the card since the class is guaranteed to be referenced from another location.
+ // Proxy classes are held live by the class loader, and other classes are roots of the class
+ // linker.
+ SetFieldPtr(OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass, false, false);
+}
+
+inline bool Object::InstanceOf(const Class* klass) const {
+ DCHECK(klass != NULL);
+ DCHECK(GetClass() != NULL);
+ return klass->IsAssignableFrom(GetClass());
+}
+
+inline bool Object::IsClass() const {
+ Class* java_lang_Class = GetClass()->GetClass();
+ return GetClass() == java_lang_Class;
+}
+
+inline Class* Object::AsClass() {
+ DCHECK(IsClass());
+ return down_cast<Class*>(this);
+}
+
+inline const Class* Object::AsClass() const {
+ DCHECK(IsClass());
+ return down_cast<const Class*>(this);
+}
+
+inline bool Object::IsObjectArray() const {
+ return IsArrayInstance() && !GetClass()->GetComponentType()->IsPrimitive();
+}
+
+template<class T>
+inline ObjectArray<T>* Object::AsObjectArray() {
+ DCHECK(IsObjectArray());
+ return down_cast<ObjectArray<T>*>(this);
+}
+
+template<class T>
+inline const ObjectArray<T>* Object::AsObjectArray() const {
+ DCHECK(IsObjectArray());
+ return down_cast<const ObjectArray<T>*>(this);
+}
+
+inline bool Object::IsArrayInstance() const {
+ return GetClass()->IsArrayClass();
+}
+
+inline bool Object::IsField() const {
+ return GetClass()->IsFieldClass();
+}
+
+inline Field* Object::AsField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(IsField());
+ return down_cast<Field*>(this);
+}
+
+inline const Field* Object::AsField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(IsField());
+ return down_cast<const Field*>(this);
+}
+
+inline bool Object::IsMethod() const {
+ return GetClass()->IsMethodClass();
+}
+
+inline AbstractMethod* Object::AsMethod() {
+ DCHECK(IsMethod());
+ return down_cast<AbstractMethod*>(this);
+}
+
+inline const AbstractMethod* Object::AsMethod() const {
+ DCHECK(IsMethod());
+ return down_cast<const AbstractMethod*>(this);
+}
+
+inline bool Object::IsReferenceInstance() const {
+ return GetClass()->IsReferenceClass();
+}
+
+inline bool Object::IsWeakReferenceInstance() const {
+ return GetClass()->IsWeakReferenceClass();
+}
+
+inline bool Object::IsSoftReferenceInstance() const {
+ return GetClass()->IsSoftReferenceClass();
+}
+
+inline bool Object::IsFinalizerReferenceInstance() const {
+ return GetClass()->IsFinalizerReferenceClass();
+}
+
+inline bool Object::IsPhantomReferenceInstance() const {
+ return GetClass()->IsPhantomReferenceClass();
+}
+
+inline size_t Object::SizeOf() const {
+ size_t result;
+ if (IsArrayInstance()) {
+ result = AsArray()->SizeOf();
+ } else if (IsClass()) {
+ result = AsClass()->SizeOf();
+ } else {
+ result = GetClass()->GetObjectSize();
+ }
+ DCHECK(!IsField() || result == sizeof(Field));
+ DCHECK(!IsMethod() || result == sizeof(AbstractMethod));
+ return result;
+}
+
+inline uint64_t Object::GetField64(MemberOffset field_offset, bool is_volatile) const {
+ VerifyObject(this);
+ const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
+ const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr);
+ if (UNLIKELY(is_volatile)) {
+ uint64_t result = QuasiAtomic::Read64(addr);
+ ANDROID_MEMBAR_FULL();
+ return result;
+ } else {
+ return *addr;
+ }
+}
+
+inline void Object::SetField64(MemberOffset field_offset, uint64_t new_value, bool is_volatile) {
+ VerifyObject(this);
+ byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
+ int64_t* addr = reinterpret_cast<int64_t*>(raw_addr);
+ if (UNLIKELY(is_volatile)) {
+ ANDROID_MEMBAR_STORE();
+ QuasiAtomic::Write64(addr, new_value);
+ // Post-store barrier not required due to use of atomic op or mutex.
+ } else {
+ *addr = new_value;
+ }
+}
+
+inline void Object::WriteBarrierField(const Object* dst, MemberOffset field_offset,
+ const Object* new_value) {
+ Runtime::Current()->GetHeap()->WriteBarrierField(dst, field_offset, new_value);
+}
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_OBJECT_INL_H_
diff --git a/src/mirror/object.cc b/src/mirror/object.cc
new file mode 100644
index 0000000..27a42d3
--- /dev/null
+++ b/src/mirror/object.cc
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "object.h"
+
+#include "array-inl.h"
+#include "class.h"
+#include "class-inl.h"
+#include "field.h"
+#include "field-inl.h"
+#include "gc/card_table-inl.h"
+#include "heap.h"
+#include "monitor.h"
+#include "object-inl.h"
+#include "object_array.h"
+#include "object_utils.h"
+#include "runtime.h"
+#include "sirt_ref.h"
+#include "throwable.h"
+#include "well_known_classes.h"
+
+namespace art {
+namespace mirror {
+
+Array* Object::AsArray() {
+ DCHECK(IsArrayInstance());
+ return down_cast<Array*>(this);
+}
+
+const Array* Object::AsArray() const {
+ DCHECK(IsArrayInstance());
+ return down_cast<const Array*>(this);
+}
+
+BooleanArray* Object::AsBooleanArray() {
+ DCHECK(GetClass()->IsArrayClass());
+ DCHECK(GetClass()->GetComponentType()->IsPrimitiveBoolean());
+ return down_cast<BooleanArray*>(this);
+}
+
+ByteArray* Object::AsByteArray() {
+ DCHECK(GetClass()->IsArrayClass());
+ DCHECK(GetClass()->GetComponentType()->IsPrimitiveByte());
+ return down_cast<ByteArray*>(this);
+}
+
+CharArray* Object::AsCharArray() {
+ DCHECK(GetClass()->IsArrayClass());
+ DCHECK(GetClass()->GetComponentType()->IsPrimitiveChar());
+ return down_cast<CharArray*>(this);
+}
+
+ShortArray* Object::AsShortArray() {
+ DCHECK(GetClass()->IsArrayClass());
+ DCHECK(GetClass()->GetComponentType()->IsPrimitiveShort());
+ return down_cast<ShortArray*>(this);
+}
+
+IntArray* Object::AsIntArray() {
+ DCHECK(GetClass()->IsArrayClass());
+ DCHECK(GetClass()->GetComponentType()->IsPrimitiveInt() ||
+ GetClass()->GetComponentType()->IsPrimitiveFloat());
+ return down_cast<IntArray*>(this);
+}
+
+LongArray* Object::AsLongArray() {
+ DCHECK(GetClass()->IsArrayClass());
+ DCHECK(GetClass()->GetComponentType()->IsPrimitiveLong() ||
+ GetClass()->GetComponentType()->IsPrimitiveDouble());
+ return down_cast<LongArray*>(this);
+}
+
+String* Object::AsString() {
+ DCHECK(GetClass()->IsStringClass());
+ return down_cast<String*>(this);
+}
+
+Throwable* Object::AsThrowable() {
+ DCHECK(GetClass()->IsThrowableClass());
+ return down_cast<Throwable*>(this);
+}
+
+Object* Object::Clone(Thread* self) {
+ Class* c = GetClass();
+ DCHECK(!c->IsClassClass());
+
+ // Object::SizeOf gets the right size even if we're an array.
+ // Using c->AllocObject() here would be wrong.
+ size_t num_bytes = SizeOf();
+ Heap* heap = Runtime::Current()->GetHeap();
+ SirtRef<Object> copy(self, heap->AllocObject(self, c, num_bytes));
+ if (copy.get() == NULL) {
+ return NULL;
+ }
+
+ // Copy instance data. We assume memcpy copies by words.
+ // TODO: expose and use move32.
+ byte* src_bytes = reinterpret_cast<byte*>(this);
+ byte* dst_bytes = reinterpret_cast<byte*>(copy.get());
+ size_t offset = sizeof(Object);
+ memcpy(dst_bytes + offset, src_bytes + offset, num_bytes - offset);
+
+ // Perform write barriers on copied object references.
+ if (c->IsArrayClass()) {
+ if (!c->GetComponentType()->IsPrimitive()) {
+ const ObjectArray<Object>* array = copy->AsObjectArray<Object>();
+ heap->WriteBarrierArray(copy.get(), 0, array->GetLength());
+ }
+ } else {
+ for (const Class* klass = c; klass != NULL; klass = klass->GetSuperClass()) {
+ size_t num_reference_fields = klass->NumReferenceInstanceFields();
+ for (size_t i = 0; i < num_reference_fields; ++i) {
+ Field* field = klass->GetInstanceField(i);
+ MemberOffset field_offset = field->GetOffset();
+ const Object* ref = copy->GetFieldObject<const Object*>(field_offset, false);
+ heap->WriteBarrierField(copy.get(), field_offset, ref);
+ }
+ }
+ }
+
+ if (c->IsFinalizable()) {
+ heap->AddFinalizerReference(Thread::Current(), copy.get());
+ }
+
+ return copy.get();
+}
+
+uint32_t Object::GetThinLockId() {
+ return Monitor::GetThinLockId(monitor_);
+}
+
+void Object::MonitorEnter(Thread* thread) {
+ Monitor::MonitorEnter(thread, this);
+}
+
+bool Object::MonitorExit(Thread* thread) {
+ return Monitor::MonitorExit(thread, this);
+}
+
+void Object::Notify() {
+ Monitor::Notify(Thread::Current(), this);
+}
+
+void Object::NotifyAll() {
+ Monitor::NotifyAll(Thread::Current(), this);
+}
+
+void Object::Wait() {
+ Monitor::Wait(Thread::Current(), this, 0, 0, true, kWaiting);
+}
+
+void Object::Wait(int64_t ms, int32_t ns) {
+ Monitor::Wait(Thread::Current(), this, ms, ns, true, kTimedWaiting);
+}
+
+#if VERIFY_OBJECT_ENABLED
+void Object::CheckFieldAssignment(MemberOffset field_offset, const Object* new_value) {
+ const Class* c = GetClass();
+ if (Runtime::Current()->GetClassLinker() == NULL ||
+ !Runtime::Current()->GetHeap()->IsObjectValidationEnabled() ||
+ !c->IsResolved()) {
+ return;
+ }
+ for (const Class* cur = c; cur != NULL; cur = cur->GetSuperClass()) {
+ ObjectArray<Field>* fields = cur->GetIFields();
+ if (fields != NULL) {
+ size_t num_ref_ifields = cur->NumReferenceInstanceFields();
+ for (size_t i = 0; i < num_ref_ifields; ++i) {
+ Field* field = fields->Get(i);
+ if (field->GetOffset().Int32Value() == field_offset.Int32Value()) {
+ FieldHelper fh(field);
+ CHECK(fh.GetType()->IsAssignableFrom(new_value->GetClass()));
+ return;
+ }
+ }
+ }
+ }
+ if (c->IsArrayClass()) {
+ // Bounds and assign-ability done in the array setter.
+ return;
+ }
+ if (IsClass()) {
+ ObjectArray<Field>* fields = AsClass()->GetSFields();
+ if (fields != NULL) {
+ size_t num_ref_sfields = AsClass()->NumReferenceStaticFields();
+ for (size_t i = 0; i < num_ref_sfields; ++i) {
+ Field* field = fields->Get(i);
+ if (field->GetOffset().Int32Value() == field_offset.Int32Value()) {
+ FieldHelper fh(field);
+ CHECK(fh.GetType()->IsAssignableFrom(new_value->GetClass()));
+ return;
+ }
+ }
+ }
+ }
+ LOG(FATAL) << "Failed to find field for assignment to " << reinterpret_cast<void*>(this)
+ << " of type " << PrettyDescriptor(c) << " at offset " << field_offset;
+}
+#endif
+
+} // namespace mirror
+} // namespace art
diff --git a/src/mirror/object.h b/src/mirror/object.h
new file mode 100644
index 0000000..e2cedd8
--- /dev/null
+++ b/src/mirror/object.h
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_OBJECT_H_
+#define ART_SRC_MIRROR_OBJECT_H_
+
+#include "base/casts.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "cutils/atomic-inline.h"
+#include "offsets.h"
+
+namespace art {
+
+class ImageWriter;
+struct ObjectOffsets;
+class Thread;
+
+namespace mirror {
+
+class AbstractMethod;
+class Array;
+class Class;
+class Field;
+template<class T> class ObjectArray;
+template<class T> class PrimitiveArray;
+typedef PrimitiveArray<uint8_t> BooleanArray;
+typedef PrimitiveArray<int8_t> ByteArray;
+typedef PrimitiveArray<uint16_t> CharArray;
+typedef PrimitiveArray<double> DoubleArray;
+typedef PrimitiveArray<float> FloatArray;
+typedef PrimitiveArray<int32_t> IntArray;
+typedef PrimitiveArray<int64_t> LongArray;
+typedef PrimitiveArray<int16_t> ShortArray;
+class String;
+class Throwable;
+
+// Classes shared with the managed side of the world need to be packed so that they don't have
+// extra platform specific padding.
+#define MANAGED PACKED(4)
+
+// Fields within mirror objects aren't accessed directly so that the appropriate amount of
+// handshaking is done with GC (for example, read and write barriers). This macro is used to
+// compute an offset for the Set/Get methods defined in Object that can safely access fields.
+#define OFFSET_OF_OBJECT_MEMBER(type, field) \
+ MemberOffset(OFFSETOF_MEMBER(type, field))
+
+// C++ mirror of java.lang.Object
+class MANAGED Object {
+ public:
+ static MemberOffset ClassOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(Object, klass_);
+ }
+
+ Class* GetClass() const;
+
+ void SetClass(Class* new_klass);
+
+ bool InstanceOf(const Class* klass) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ size_t SizeOf() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ Object* Clone(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ int32_t IdentityHashCode() const {
+ #ifdef MOVING_GARBAGE_COLLECTOR
+ // TODO: we'll need to use the Object's internal concept of identity
+ UNIMPLEMENTED(FATAL);
+ #endif
+ return reinterpret_cast<int32_t>(this);
+ }
+
+ static MemberOffset MonitorOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(Object, monitor_);
+ }
+
+ volatile int32_t* GetRawLockWordAddress() {
+ byte* raw_addr = reinterpret_cast<byte*>(this) +
+ OFFSET_OF_OBJECT_MEMBER(Object, monitor_).Int32Value();
+ int32_t* word_addr = reinterpret_cast<int32_t*>(raw_addr);
+ return const_cast<volatile int32_t*>(word_addr);
+ }
+
+ uint32_t GetThinLockId();
+
+ void MonitorEnter(Thread* thread) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ EXCLUSIVE_LOCK_FUNCTION(monitor_lock_);
+
+ bool MonitorExit(Thread* thread) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ UNLOCK_FUNCTION(monitor_lock_);
+
+ void Notify() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void NotifyAll() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void Wait() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void Wait(int64_t timeout) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void Wait(int64_t timeout, int32_t nanos) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ bool IsClass() const;
+
+ Class* AsClass();
+
+ const Class* AsClass() const;
+
+ bool IsObjectArray() const;
+
+ template<class T>
+ ObjectArray<T>* AsObjectArray();
+
+ template<class T>
+ const ObjectArray<T>* AsObjectArray() const;
+
+ bool IsArrayInstance() const;
+
+ Array* AsArray();
+
+ const Array* AsArray() const;
+
+ BooleanArray* AsBooleanArray();
+ ByteArray* AsByteArray();
+ CharArray* AsCharArray();
+ ShortArray* AsShortArray();
+ IntArray* AsIntArray();
+ LongArray* AsLongArray();
+
+ String* AsString();
+
+ Throwable* AsThrowable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ bool IsMethod() const;
+
+ AbstractMethod* AsMethod();
+
+ const AbstractMethod* AsMethod() const;
+
+ bool IsField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ Field* AsField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ const Field* AsField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ bool IsReferenceInstance() const;
+
+ bool IsWeakReferenceInstance() const;
+
+ bool IsSoftReferenceInstance() const;
+
+ bool IsFinalizerReferenceInstance() const;
+
+ bool IsPhantomReferenceInstance() const;
+
+ // Accessors for Java type fields
+ template<class T>
+ T GetFieldObject(MemberOffset field_offset, bool is_volatile) const {
+ T result = reinterpret_cast<T>(GetField32(field_offset, is_volatile));
+ VerifyObject(result);
+ return result;
+ }
+
+ void SetFieldObject(MemberOffset field_offset, const Object* new_value, bool is_volatile,
+ bool this_is_valid = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ VerifyObject(new_value);
+ SetField32(field_offset, reinterpret_cast<uint32_t>(new_value), is_volatile, this_is_valid);
+ if (new_value != NULL) {
+ CheckFieldAssignment(field_offset, new_value);
+ WriteBarrierField(this, field_offset, new_value);
+ }
+ }
+
+ uint32_t GetField32(MemberOffset field_offset, bool is_volatile) const {
+ VerifyObject(this);
+ const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
+ const int32_t* word_addr = reinterpret_cast<const int32_t*>(raw_addr);
+ if (UNLIKELY(is_volatile)) {
+ return android_atomic_acquire_load(word_addr);
+ } else {
+ return *word_addr;
+ }
+ }
+
+ void SetField32(MemberOffset field_offset, uint32_t new_value, bool is_volatile,
+ bool this_is_valid = true) {
+ if (this_is_valid) {
+ VerifyObject(this);
+ }
+ byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
+ uint32_t* word_addr = reinterpret_cast<uint32_t*>(raw_addr);
+ if (UNLIKELY(is_volatile)) {
+ /*
+ * TODO: add an android_atomic_synchronization_store() function and
+ * use it in the 32-bit volatile set handlers. On some platforms we
+ * can use a fast atomic instruction and avoid the barriers.
+ */
+ ANDROID_MEMBAR_STORE();
+ *word_addr = new_value;
+ ANDROID_MEMBAR_FULL();
+ } else {
+ *word_addr = new_value;
+ }
+ }
+
+ uint64_t GetField64(MemberOffset field_offset, bool is_volatile) const;
+
+ void SetField64(MemberOffset field_offset, uint64_t new_value, bool is_volatile);
+
+ protected:
+ // Accessors for non-Java type fields
+ template<class T>
+ T GetFieldPtr(MemberOffset field_offset, bool is_volatile) const {
+ return reinterpret_cast<T>(GetField32(field_offset, is_volatile));
+ }
+
+ template<typename T>
+ void SetFieldPtr(MemberOffset field_offset, T new_value, bool is_volatile, bool this_is_valid = true) {
+ SetField32(field_offset, reinterpret_cast<uint32_t>(new_value), is_volatile, this_is_valid);
+ }
+
+ private:
+#if VERIFY_OBJECT_ENABLED
+ static void VerifyObject(const Object* obj);
+ void CheckFieldAssignment(MemberOffset field_offset, const Object* new_value)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+#else
+ static void VerifyObject(const Object*) {}
+ void CheckFieldAssignment(MemberOffset, const Object*)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {}
+#endif
+
+ // Write barrier called post update to a reference bearing field.
+ static void WriteBarrierField(const Object* dst, MemberOffset offset, const Object* new_value);
+
+ Class* klass_;
+
+ uint32_t monitor_;
+
+ friend class art::ImageWriter;
+ friend struct art::ObjectOffsets; // for verifying offset information
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
+};
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_OBJECT_H_
diff --git a/src/mirror/object_array-inl.h b/src/mirror/object_array-inl.h
new file mode 100644
index 0000000..d981428
--- /dev/null
+++ b/src/mirror/object_array-inl.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_OBJECT_ARRAY_INL_H_
+#define ART_SRC_MIRROR_OBJECT_ARRAY_INL_H_
+
+#include "object_array.h"
+
+#include "heap.h"
+#include "mirror/class.h"
+#include "mirror/field.h"
+#include "runtime.h"
+
+namespace art {
+namespace mirror {
+
+template<class T>
+inline 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 {
+ return array->AsObjectArray<T>();
+ }
+}
+
+template<class T>
+inline T* ObjectArray<T>::Get(int32_t i) const {
+ if (UNLIKELY(!IsValidIndex(i))) {
+ return NULL;
+ }
+ MemberOffset data_offset(DataOffset(sizeof(Object*)).Int32Value() + i * sizeof(Object*));
+ return GetFieldObject<T*>(data_offset, false);
+}
+
+template<class T>
+inline void ObjectArray<T>::Set(int32_t i, T* object) {
+ if (LIKELY(IsValidIndex(i))) {
+ if (object != NULL) {
+ Class* element_class = GetClass()->GetComponentType();
+ if (UNLIKELY(!object->InstanceOf(element_class))) {
+ ThrowArrayStoreException(object);
+ return;
+ }
+ }
+ MemberOffset data_offset(DataOffset(sizeof(Object*)).Int32Value() + i * sizeof(Object*));
+ SetFieldObject(data_offset, object, false);
+ }
+}
+
+template<class T>
+inline void ObjectArray<T>::SetWithoutChecks(int32_t i, T* object) {
+ DCHECK(IsValidIndex(i));
+ MemberOffset data_offset(DataOffset(sizeof(Object*)).Int32Value() + i * sizeof(Object*));
+ SetFieldObject(data_offset, object, false);
+}
+
+template<class T>
+inline void ObjectArray<T>::SetPtrWithoutChecks(int32_t i, T* object) {
+ DCHECK(IsValidIndex(i));
+ MemberOffset data_offset(DataOffset(sizeof(Object*)).Int32Value() + i * sizeof(Object*));
+ SetFieldPtr(data_offset, object, false);
+}
+
+template<class T>
+inline T* ObjectArray<T>::GetWithoutChecks(int32_t i) const {
+ DCHECK(IsValidIndex(i));
+ MemberOffset data_offset(DataOffset(sizeof(Object*)).Int32Value() + i * sizeof(Object*));
+ return GetFieldObject<T*>(data_offset, false);
+}
+
+template<class T>
+inline void ObjectArray<T>::Copy(const ObjectArray<T>* src, int src_pos,
+ ObjectArray<T>* dst, int dst_pos,
+ size_t length) {
+ if (src->IsValidIndex(src_pos) &&
+ src->IsValidIndex(src_pos+length-1) &&
+ dst->IsValidIndex(dst_pos) &&
+ dst->IsValidIndex(dst_pos+length-1)) {
+ MemberOffset src_offset(DataOffset(sizeof(Object*)).Int32Value() + src_pos * sizeof(Object*));
+ MemberOffset dst_offset(DataOffset(sizeof(Object*)).Int32Value() + dst_pos * sizeof(Object*));
+ Class* array_class = dst->GetClass();
+ Heap* heap = Runtime::Current()->GetHeap();
+ if (array_class == src->GetClass()) {
+ // No need for array store checks if arrays are of the same type
+ for (size_t i = 0; i < length; i++) {
+ Object* object = src->GetFieldObject<Object*>(src_offset, false);
+ heap->VerifyObject(object);
+ // directly set field, we do a bulk write barrier at the end
+ dst->SetField32(dst_offset, reinterpret_cast<uint32_t>(object), false, true);
+ src_offset = MemberOffset(src_offset.Uint32Value() + sizeof(Object*));
+ dst_offset = MemberOffset(dst_offset.Uint32Value() + sizeof(Object*));
+ }
+ } else {
+ Class* element_class = array_class->GetComponentType();
+ CHECK(!element_class->IsPrimitive());
+ for (size_t i = 0; i < length; i++) {
+ Object* object = src->GetFieldObject<Object*>(src_offset, false);
+ if (object != NULL && !object->InstanceOf(element_class)) {
+ dst->ThrowArrayStoreException(object);
+ return;
+ }
+ heap->VerifyObject(object);
+ // directly set field, we do a bulk write barrier at the end
+ dst->SetField32(dst_offset, reinterpret_cast<uint32_t>(object), false, true);
+ src_offset = MemberOffset(src_offset.Uint32Value() + sizeof(Object*));
+ dst_offset = MemberOffset(dst_offset.Uint32Value() + sizeof(Object*));
+ }
+ }
+ heap->WriteBarrierArray(dst, dst_pos, length);
+ }
+}
+
+template<class T>
+inline 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;
+}
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_OBJET_ARRAY_INL_H_
diff --git a/src/mirror/object_array.h b/src/mirror/object_array.h
new file mode 100644
index 0000000..3d04b39
--- /dev/null
+++ b/src/mirror/object_array.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_OBJECT_ARRAY_H_
+#define ART_SRC_MIRROR_OBJECT_ARRAY_H_
+
+#include "array.h"
+
+namespace art {
+namespace mirror {
+
+template<class T>
+class MANAGED ObjectArray : public Array {
+ public:
+ 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_);
+
+ void Set(int32_t i, T* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Set element without bound and element type checks, to be used in limited
+ // circumstances, such as during boot image writing
+ void SetWithoutChecks(int32_t i, T* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Set element without bound and element type checks, to be used in limited circumstances, such
+ // as during boot image writing. Does not do write barrier.
+ void SetPtrWithoutChecks(int32_t i, T* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ T* GetWithoutChecks(int32_t i) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static void Copy(const ObjectArray<T>* src, int src_pos,
+ ObjectArray<T>* dst, int dst_pos,
+ size_t length)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ ObjectArray<T>* CopyOf(Thread* self, int32_t new_length)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectArray);
+};
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_OBJECT_ARRAY_H_
diff --git a/src/object_test.cc b/src/mirror/object_test.cc
similarity index 98%
rename from src/object_test.cc
rename to src/mirror/object_test.cc
index f3b6a19..29cf2f1 100644
--- a/src/object_test.cc
+++ b/src/mirror/object_test.cc
@@ -19,16 +19,26 @@
#include <stdint.h>
#include <stdio.h>
+#include "array-inl.h"
#include "asm_support.h"
+#include "class-inl.h"
#include "class_linker.h"
+#include "class_linker-inl.h"
#include "common_test.h"
#include "dex_file.h"
+#include "field-inl.h"
+#include "gc/card_table-inl.h"
#include "heap.h"
+#include "iftable-inl.h"
+#include "abstract_method-inl.h"
+#include "object-inl.h"
+#include "object_array-inl.h"
#include "runtime_support.h"
#include "sirt_ref.h"
#include "UniquePtr.h"
namespace art {
+namespace mirror {
class ObjectTest : public CommonTest {
protected:
@@ -626,4 +636,5 @@
// TODO: test that interfaces trump superclasses.
}
+} // namespace mirror
} // namespace art
diff --git a/src/mirror/proxy.h b/src/mirror/proxy.h
new file mode 100644
index 0000000..cac028a
--- /dev/null
+++ b/src/mirror/proxy.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_PROXY_H_
+#define ART_SRC_MIRROR_PROXY_H_
+
+#include "mirror/object.h"
+
+namespace art {
+
+struct ProxyOffsets;
+
+namespace mirror {
+
+class MANAGED SynthesizedProxyClass : public Class {
+ public:
+ ObjectArray<Class>* GetInterfaces() {
+ return interfaces_;
+ }
+
+ ObjectArray<ObjectArray<Class> >* GetThrows() {
+ return throws_;
+ }
+
+ private:
+ ObjectArray<Class>* interfaces_;
+ ObjectArray<ObjectArray<Class> >* throws_;
+ DISALLOW_IMPLICIT_CONSTRUCTORS(SynthesizedProxyClass);
+};
+
+class MANAGED Proxy : public Object {
+ private:
+ Object* h_;
+
+ friend struct art::ProxyOffsets; // for verifying offset information
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Proxy);
+};
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_PROXY_H_
diff --git a/src/mirror/stack_trace_element.cc b/src/mirror/stack_trace_element.cc
new file mode 100644
index 0000000..9d557ec
--- /dev/null
+++ b/src/mirror/stack_trace_element.cc
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "stack_trace_element.h"
+
+#include "class.h"
+#include "gc/card_table-inl.h"
+#include "object-inl.h"
+#include "string.h"
+
+namespace art {
+namespace mirror {
+
+Class* StackTraceElement::java_lang_StackTraceElement_ = NULL;
+
+void StackTraceElement::SetClass(Class* java_lang_StackTraceElement) {
+ CHECK(java_lang_StackTraceElement_ == NULL);
+ CHECK(java_lang_StackTraceElement != NULL);
+ java_lang_StackTraceElement_ = java_lang_StackTraceElement;
+}
+
+void StackTraceElement::ResetClass() {
+ CHECK(java_lang_StackTraceElement_ != NULL);
+ java_lang_StackTraceElement_ = NULL;
+}
+
+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(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_),
+ const_cast<String*>(method_name), false);
+ trace->SetFieldObject(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, file_name_),
+ const_cast<String*>(file_name), false);
+ trace->SetField32(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, line_number_),
+ line_number, false);
+ return trace;
+}
+
+} // namespace mirror
+} // namespace art
diff --git a/src/mirror/stack_trace_element.h b/src/mirror/stack_trace_element.h
new file mode 100644
index 0000000..d53c860
--- /dev/null
+++ b/src/mirror/stack_trace_element.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_STACK_TRACE_ELEMENT_H_
+#define ART_SRC_MIRROR_STACK_TRACE_ELEMENT_H_
+
+#include "object.h"
+
+namespace art {
+
+struct StackTraceElementOffsets;
+
+namespace mirror {
+
+// C++ mirror of java.lang.StackTraceElement
+class MANAGED StackTraceElement : public Object {
+ public:
+ const String* GetDeclaringClass() const {
+ return GetFieldObject<const String*>(
+ OFFSET_OF_OBJECT_MEMBER(StackTraceElement, declaring_class_), false);
+ }
+
+ const String* GetMethodName() const {
+ return GetFieldObject<const String*>(
+ OFFSET_OF_OBJECT_MEMBER(StackTraceElement, method_name_), false);
+ }
+
+ const String* GetFileName() const {
+ return GetFieldObject<const String*>(
+ OFFSET_OF_OBJECT_MEMBER(StackTraceElement, file_name_), false);
+ }
+
+ int32_t GetLineNumber() const {
+ return GetField32(
+ OFFSET_OF_OBJECT_MEMBER(StackTraceElement, line_number_), false);
+ }
+
+ static StackTraceElement* Alloc(Thread* self,
+ String* declaring_class,
+ String* method_name,
+ String* file_name,
+ int32_t line_number)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static void SetClass(Class* java_lang_StackTraceElement);
+
+ static void ResetClass();
+
+ private:
+ // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
+ String* declaring_class_;
+ String* file_name_;
+ String* method_name_;
+ int32_t line_number_;
+
+ static Class* GetStackTraceElement() {
+ DCHECK(java_lang_StackTraceElement_ != NULL);
+ return java_lang_StackTraceElement_;
+ }
+
+ static Class* java_lang_StackTraceElement_;
+
+ friend struct art::StackTraceElementOffsets; // for verifying offset information
+ DISALLOW_IMPLICIT_CONSTRUCTORS(StackTraceElement);
+};
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_STACK_TRACE_ELEMENT_H_
diff --git a/src/mirror/string.cc b/src/mirror/string.cc
new file mode 100644
index 0000000..f571fb8
--- /dev/null
+++ b/src/mirror/string.cc
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "string.h"
+
+#include "array.h"
+#include "gc/card_table-inl.h"
+#include "intern_table.h"
+#include "object-inl.h"
+#include "runtime.h"
+#include "sirt_ref.h"
+#include "thread.h"
+#include "utf.h"
+
+namespace art {
+namespace mirror {
+
+const CharArray* String::GetCharArray() const {
+ return GetFieldObject<const CharArray*>(ValueOffset(), false);
+}
+
+void String::ComputeHashCode() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ SetHashCode(ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()));
+}
+
+int32_t String::GetUtfLength() const {
+ return CountUtf8Bytes(GetCharArray()->GetData() + GetOffset(), GetLength());
+}
+
+int32_t String::FastIndexOf(int32_t ch, int32_t start) const {
+ int32_t count = GetLength();
+ if (start < 0) {
+ start = 0;
+ } else if (start > count) {
+ start = count;
+ }
+ const uint16_t* chars = GetCharArray()->GetData() + GetOffset();
+ const uint16_t* p = chars + start;
+ const uint16_t* end = chars + count;
+ while (p < end) {
+ if (*p++ == ch) {
+ return (p - 1) - chars;
+ }
+ }
+ return -1;
+}
+
+void String::SetArray(CharArray* new_array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ DCHECK(new_array != NULL);
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(String, array_), new_array, false);
+}
+
+// TODO: get global references for these
+Class* String::java_lang_String_ = NULL;
+
+void String::SetClass(Class* java_lang_String) {
+ CHECK(java_lang_String_ == NULL);
+ CHECK(java_lang_String != NULL);
+ java_lang_String_ = java_lang_String;
+}
+
+void String::ResetClass() {
+ CHECK(java_lang_String_ != NULL);
+ java_lang_String_ = NULL;
+}
+
+String* String::Intern() {
+ return Runtime::Current()->GetInternTable()->InternWeak(this);
+}
+
+int32_t String::GetHashCode() {
+ int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
+ if (result == 0) {
+ ComputeHashCode();
+ }
+ result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
+ DCHECK(result != 0 || ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()) == 0)
+ << ToModifiedUtf8() << " " << result;
+ return result;
+}
+
+int32_t String::GetLength() const {
+ int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, count_), false);
+ DCHECK(result >= 0 && result <= GetCharArray()->GetLength());
+ return result;
+}
+
+uint16_t String::CharAt(int32_t index) const {
+ // TODO: do we need this? Equals is the only caller, and could
+ // bounds check itself.
+ if (index < 0 || index >= count_) {
+ Thread* self = Thread::Current();
+ self->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
+ "length=%i; index=%i", count_, index);
+ return 0;
+ }
+ return GetCharArray()->Get(index + GetOffset());
+}
+
+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(self, GetJavaLangString(), utf16_length);
+ if (string == NULL) {
+ return NULL;
+ }
+ // TODO: use 16-bit wide memset variant
+ CharArray* array = const_cast<CharArray*>(string->GetCharArray());
+ if (array == NULL) {
+ return NULL;
+ }
+ for (int i = 0; i < utf16_length; i++) {
+ array->Set(i, utf16_data_in[i]);
+ }
+ if (hash_code != 0) {
+ string->SetHashCode(hash_code);
+ } else {
+ string->ComputeHashCode();
+ }
+ return string;
+}
+
+ String* String::AllocFromModifiedUtf8(Thread* self, const char* utf) {
+ if (utf == NULL) {
+ return NULL;
+ }
+ size_t char_count = CountModifiedUtf8Chars(utf);
+ return AllocFromModifiedUtf8(self, char_count, utf);
+}
+
+String* String::AllocFromModifiedUtf8(Thread* self, int32_t utf16_length,
+ const char* utf8_data_in) {
+ String* string = Alloc(self, GetJavaLangString(), utf16_length);
+ if (string == NULL) {
+ return NULL;
+ }
+ uint16_t* utf16_data_out =
+ const_cast<uint16_t*>(string->GetCharArray()->GetData());
+ ConvertModifiedUtf8ToUtf16(utf16_data_out, utf8_data_in);
+ string->ComputeHashCode();
+ return string;
+}
+
+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(self, java_lang_String, array.get());
+}
+
+String* String::Alloc(Thread* self, Class* java_lang_String, CharArray* array) {
+ // Hold reference in case AllocObject causes GC.
+ SirtRef<CharArray> array_ref(self, array);
+ String* string = down_cast<String*>(java_lang_String->AllocObject(self));
+ if (string == NULL) {
+ return NULL;
+ }
+ string->SetArray(array);
+ string->SetCount(array->GetLength());
+ return string;
+}
+
+bool String::Equals(const String* that) const {
+ if (this == that) {
+ // Quick reference equality test
+ return true;
+ } else if (that == NULL) {
+ // Null isn't an instanceof anything
+ return false;
+ } else if (this->GetLength() != that->GetLength()) {
+ // Quick length inequality test
+ return false;
+ } else {
+ // Note: don't short circuit on hash code as we're presumably here as the
+ // hash code was already equal
+ for (int32_t i = 0; i < that->GetLength(); ++i) {
+ if (this->CharAt(i) != that->CharAt(i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+
+bool String::Equals(const uint16_t* that_chars, int32_t that_offset, int32_t that_length) const {
+ if (this->GetLength() != that_length) {
+ return false;
+ } else {
+ for (int32_t i = 0; i < that_length; ++i) {
+ if (this->CharAt(i) != that_chars[that_offset + i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
+
+bool String::Equals(const char* modified_utf8) const {
+ for (int32_t i = 0; i < GetLength(); ++i) {
+ uint16_t ch = GetUtf16FromUtf8(&modified_utf8);
+ if (ch == '\0' || ch != CharAt(i)) {
+ return false;
+ }
+ }
+ return *modified_utf8 == '\0';
+}
+
+bool String::Equals(const StringPiece& modified_utf8) const {
+ if (modified_utf8.size() != GetLength()) {
+ return false;
+ }
+ const char* p = modified_utf8.data();
+ for (int32_t i = 0; i < GetLength(); ++i) {
+ uint16_t ch = GetUtf16FromUtf8(&p);
+ if (ch != CharAt(i)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+// Create a modified UTF-8 encoded std::string from a java/lang/String object.
+std::string String::ToModifiedUtf8() const {
+ const uint16_t* chars = GetCharArray()->GetData() + GetOffset();
+ size_t byte_count = GetUtfLength();
+ std::string result(byte_count, static_cast<char>(0));
+ ConvertUtf16ToModifiedUtf8(&result[0], chars, GetLength());
+ return result;
+}
+
+#ifdef HAVE__MEMCMP16
+// "count" is in 16-bit units.
+extern "C" uint32_t __memcmp16(const uint16_t* s0, const uint16_t* s1, size_t count);
+#define MemCmp16 __memcmp16
+#else
+static uint32_t MemCmp16(const uint16_t* s0, const uint16_t* s1, size_t count) {
+ for (size_t i = 0; i < count; i++) {
+ if (s0[i] != s1[i]) {
+ return static_cast<int32_t>(s0[i]) - static_cast<int32_t>(s1[i]);
+ }
+ }
+ return 0;
+}
+#endif
+
+int32_t String::CompareTo(String* rhs) const {
+ // Quick test for comparison of a string with itself.
+ const String* lhs = this;
+ if (lhs == rhs) {
+ return 0;
+ }
+ // TODO: is this still true?
+ // The annoying part here is that 0x00e9 - 0xffff != 0x00ea,
+ // because the interpreter converts the characters to 32-bit integers
+ // *without* sign extension before it subtracts them (which makes some
+ // sense since "char" is unsigned). So what we get is the result of
+ // 0x000000e9 - 0x0000ffff, which is 0xffff00ea.
+ int lhsCount = lhs->GetLength();
+ int rhsCount = rhs->GetLength();
+ int countDiff = lhsCount - rhsCount;
+ int minCount = (countDiff < 0) ? lhsCount : rhsCount;
+ const uint16_t* lhsChars = lhs->GetCharArray()->GetData() + lhs->GetOffset();
+ const uint16_t* rhsChars = rhs->GetCharArray()->GetData() + rhs->GetOffset();
+ int otherRes = MemCmp16(lhsChars, rhsChars, minCount);
+ if (otherRes != 0) {
+ return otherRes;
+ }
+ return countDiff;
+}
+
+} // namespace mirror
+} // namespace art
+
diff --git a/src/mirror/string.h b/src/mirror/string.h
new file mode 100644
index 0000000..ef74fed
--- /dev/null
+++ b/src/mirror/string.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_STRING_H_
+#define ART_SRC_MIRROR_STRING_H_
+
+#include "class.h"
+#include "gtest/gtest.h"
+
+namespace art {
+
+struct StringClassOffsets;
+struct StringOffsets;
+class StringPiece;
+
+namespace mirror {
+
+// C++ mirror of java.lang.String
+class MANAGED String : public Object {
+ public:
+ static MemberOffset CountOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(String, count_);
+ }
+
+ static MemberOffset ValueOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(String, array_);
+ }
+
+ static MemberOffset OffsetOffset() {
+ return OFFSET_OF_OBJECT_MEMBER(String, offset_);
+ }
+
+ const CharArray* GetCharArray() const;
+
+ int32_t GetOffset() const {
+ int32_t result = GetField32(OffsetOffset(), false);
+ DCHECK_LE(0, result);
+ return result;
+ }
+
+ int32_t GetLength() const;
+
+ int32_t GetHashCode() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ void ComputeHashCode() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ int32_t GetUtfLength() const;
+
+ uint16_t CharAt(int32_t index) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ String* Intern() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ 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(Thread* self, const char* utf)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static String* AllocFromModifiedUtf8(Thread* self, int32_t utf16_length,
+ const char* utf8_data_in)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static String* Alloc(Thread* self, Class* java_lang_String, int32_t utf16_length)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static String* Alloc(Thread* self, Class* java_lang_String, CharArray* array)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ bool Equals(const char* modified_utf8) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // TODO: do we need this overload? give it a more intention-revealing name.
+ bool Equals(const StringPiece& modified_utf8) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ bool Equals(const String* that) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Compare UTF-16 code point values not in a locale-sensitive manner
+ int Compare(int32_t utf16_length, const char* utf8_data_in);
+
+ // TODO: do we need this overload? give it a more intention-revealing name.
+ bool Equals(const uint16_t* that_chars, int32_t that_offset,
+ int32_t that_length) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Create a modified UTF-8 encoded std::string from a java/lang/String object.
+ std::string ToModifiedUtf8() const;
+
+ int32_t FastIndexOf(int32_t ch, int32_t start) const;
+
+ int32_t CompareTo(String* other) const;
+
+ static Class* GetJavaLangString() {
+ DCHECK(java_lang_String_ != NULL);
+ return java_lang_String_;
+ }
+
+ static void SetClass(Class* java_lang_String);
+ static void ResetClass();
+
+ private:
+ void SetHashCode(int32_t new_hash_code) {
+ DCHECK_EQ(0u,
+ GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false));
+ SetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_),
+ new_hash_code, false);
+ }
+
+ void SetCount(int32_t new_count) {
+ DCHECK_LE(0, new_count);
+ SetField32(OFFSET_OF_OBJECT_MEMBER(String, count_), new_count, false);
+ }
+
+ void SetOffset(int32_t new_offset) {
+ DCHECK_LE(0, new_offset);
+ DCHECK_GE(GetLength(), new_offset);
+ SetField32(OFFSET_OF_OBJECT_MEMBER(String, offset_), new_offset, false);
+ }
+
+ void SetArray(CharArray* new_array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
+ CharArray* array_;
+
+ int32_t count_;
+
+ uint32_t hash_code_;
+
+ int32_t offset_;
+
+ static Class* java_lang_String_;
+
+ friend struct art::StringOffsets; // for verifying offset information
+ FRIEND_TEST(ObjectTest, StringLength); // for SetOffset and SetCount
+ DISALLOW_IMPLICIT_CONSTRUCTORS(String);
+};
+
+// TODO: remove? only used in a unit test of itself.
+struct StringHashCode {
+ int32_t operator()(String* string) const {
+ return string->GetHashCode();
+ }
+};
+
+class MANAGED StringClass : public Class {
+ private:
+ CharArray* ASCII_;
+ Object* CASE_INSENSITIVE_ORDER_;
+ uint32_t REPLACEMENT_CHAR_;
+ int64_t serialVersionUID_;
+ friend struct art::StringClassOffsets; // for verifying offset information
+ DISALLOW_IMPLICIT_CONSTRUCTORS(StringClass);
+};
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_STRING_H_
diff --git a/src/mirror/throwable.cc b/src/mirror/throwable.cc
new file mode 100644
index 0000000..bbab1dd
--- /dev/null
+++ b/src/mirror/throwable.cc
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "throwable.h"
+
+#include "abstract_method-inl.h"
+#include "class-inl.h"
+#include "gc/card_table-inl.h"
+#include "object-inl.h"
+#include "object_array.h"
+#include "object_array-inl.h"
+#include "object_utils.h"
+#include "utils.h"
+#include "well_known_classes.h"
+
+namespace art {
+namespace mirror {
+
+Class* Throwable::java_lang_Throwable_ = NULL;
+
+void Throwable::SetCause(Throwable* cause) {
+ CHECK(cause != NULL);
+ CHECK(cause != this);
+ CHECK(GetFieldObject<Throwable*>(OFFSET_OF_OBJECT_MEMBER(Throwable, cause_), false) == NULL);
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Throwable, cause_), cause, false);
+}
+
+bool Throwable::IsCheckedException() const {
+ if (InstanceOf(WellKnownClasses::ToClass(WellKnownClasses::java_lang_Error))) {
+ return false;
+ }
+ return !InstanceOf(WellKnownClasses::ToClass(WellKnownClasses::java_lang_RuntimeException));
+}
+
+std::string Throwable::Dump() const {
+ std::string result(PrettyTypeOf(this));
+ result += ": ";
+ String* msg = GetDetailMessage();
+ if (msg != NULL) {
+ result += msg->ToModifiedUtf8();
+ }
+ result += "\n";
+ Object* stack_state = GetStackState();
+ // check stack state isn't missing or corrupt
+ if (stack_state != NULL && stack_state->IsObjectArray()) {
+ // Decode the internal stack trace into the depth and method trace
+ ObjectArray<Object>* method_trace = down_cast<ObjectArray<Object>*>(stack_state);
+ int32_t depth = method_trace->GetLength() - 1;
+ IntArray* pc_trace = down_cast<IntArray*>(method_trace->Get(depth));
+ MethodHelper mh;
+ for (int32_t i = 0; i < depth; ++i) {
+ AbstractMethod* method = down_cast<AbstractMethod*>(method_trace->Get(i));
+ mh.ChangeMethod(method);
+ uint32_t dex_pc = pc_trace->Get(i);
+ int32_t line_number = mh.GetLineNumFromDexPC(dex_pc);
+ const char* source_file = mh.GetDeclaringClassSourceFile();
+ result += StringPrintf(" at %s (%s:%d)\n", PrettyMethod(method, true).c_str(),
+ source_file, line_number);
+ }
+ }
+ Throwable* cause = GetFieldObject<Throwable*>(OFFSET_OF_OBJECT_MEMBER(Throwable, cause_), false);
+ if (cause != NULL && cause != this) { // Constructor makes cause == this by default.
+ result += "Caused by: ";
+ result += cause->Dump();
+ }
+ return result;
+}
+
+void Throwable::SetClass(Class* java_lang_Throwable) {
+ CHECK(java_lang_Throwable_ == NULL);
+ CHECK(java_lang_Throwable != NULL);
+ java_lang_Throwable_ = java_lang_Throwable;
+}
+
+void Throwable::ResetClass() {
+ CHECK(java_lang_Throwable_ != NULL);
+ java_lang_Throwable_ = NULL;
+}
+
+} // namespace mirror
+} // namespace art
diff --git a/src/mirror/throwable.h b/src/mirror/throwable.h
new file mode 100644
index 0000000..aafcc07
--- /dev/null
+++ b/src/mirror/throwable.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_MIRROR_THROWABLE_H_
+#define ART_SRC_MIRROR_THROWABLE_H_
+
+#include "object.h"
+#include "string.h"
+
+namespace art {
+
+struct ThrowableOffsets;
+
+namespace mirror {
+
+// C++ mirror of java.lang.Throwable
+class MANAGED Throwable : public Object {
+ public:
+ void SetDetailMessage(String* new_detail_message) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Throwable, detail_message_), new_detail_message, false);
+ }
+ String* GetDetailMessage() const {
+ return GetFieldObject<String*>(OFFSET_OF_OBJECT_MEMBER(Throwable, detail_message_), false);
+ }
+ std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ // This is a runtime version of initCause, you shouldn't use it if initCause may have been
+ // overridden. Also it asserts rather than throwing exceptions. Currently this is only used
+ // in cases like the verifier where the checks cannot fail and initCause isn't overridden.
+ void SetCause(Throwable* cause) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ bool IsCheckedException() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ static Class* GetJavaLangThrowable() {
+ DCHECK(java_lang_Throwable_ != NULL);
+ return java_lang_Throwable_;
+ }
+
+ static void SetClass(Class* java_lang_Throwable);
+ static void ResetClass();
+
+ private:
+ Object* GetStackState() const {
+ return GetFieldObject<Object*>(OFFSET_OF_OBJECT_MEMBER(Throwable, stack_state_), true);
+ }
+
+ // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
+ Throwable* cause_;
+ String* detail_message_;
+ Object* stack_state_; // Note this is Java volatile:
+ Object* stack_trace_;
+ Object* suppressed_exceptions_;
+
+ static Class* java_lang_Throwable_;
+
+ friend struct art::ThrowableOffsets; // for verifying offset information
+ DISALLOW_IMPLICIT_CONSTRUCTORS(Throwable);
+};
+
+} // namespace mirror
+} // namespace art
+
+#endif // ART_SRC_MIRROR_THROWABLE_H_
diff --git a/src/modifiers.h b/src/modifiers.h
index ee2d4ff..78ba140 100644
--- a/src/modifiers.h
+++ b/src/modifiers.h
@@ -17,6 +17,8 @@
#ifndef ART_SRC_MODIFIERS_H_
#define ART_SRC_MODIFIERS_H_
+#include <stdint.h>
+
static const uint32_t kAccPublic = 0x0001; // class, field, method, ic
static const uint32_t kAccPrivate = 0x0002; // field, method, ic
static const uint32_t kAccProtected = 0x0004; // field, method, ic
diff --git a/src/monitor.cc b/src/monitor.cc
index 47c87cb..aa4e5ac 100644
--- a/src/monitor.cc
+++ b/src/monitor.cc
@@ -22,7 +22,9 @@
#include "base/stl_util.h"
#include "class_linker.h"
#include "dex_instruction.h"
-#include "object.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object.h"
+#include "mirror/object_array-inl.h"
#include "object_utils.h"
#include "scoped_thread_state_change.h"
#include "thread.h"
@@ -111,7 +113,7 @@
is_sensitive_thread_hook_ = is_sensitive_thread_hook;
}
-Monitor::Monitor(Thread* owner, Object* obj)
+Monitor::Monitor(Thread* owner, mirror::Object* obj)
: monitor_lock_("a monitor lock", kMonitorLock),
owner_(owner),
lock_count_(0),
@@ -186,7 +188,7 @@
}
}
-Object* Monitor::GetObject() {
+mirror::Object* Monitor::GetObject() {
return obj_;
}
@@ -200,7 +202,7 @@
uint64_t waitStart = 0;
uint64_t waitEnd = 0;
uint32_t wait_threshold = lock_profiling_threshold_;
- const AbstractMethod* current_locking_method = NULL;
+ const mirror::AbstractMethod* current_locking_method = NULL;
uint32_t current_locking_dex_pc = 0;
{
ScopedThreadStateChange tsc(self, kBlocked);
@@ -270,7 +272,7 @@
return oss.str();
}
-void Monitor::FailedUnlock(Object* o, Thread* expected_owner, Thread* found_owner,
+void Monitor::FailedUnlock(mirror::Object* o, Thread* expected_owner, Thread* found_owner,
Monitor* monitor) {
Thread* current_owner = NULL;
std::string current_owner_string;
@@ -426,7 +428,7 @@
int prev_lock_count = lock_count_;
lock_count_ = 0;
owner_ = NULL;
- const AbstractMethod* saved_method = locking_method_;
+ const mirror::AbstractMethod* saved_method = locking_method_;
locking_method_ = NULL;
uintptr_t saved_dex_pc = locking_dex_pc_;
locking_dex_pc_ = 0;
@@ -570,7 +572,7 @@
* Changes the shape of a monitor from thin to fat, preserving the
* internal lock state. The calling thread must own the lock.
*/
-void Monitor::Inflate(Thread* self, Object* obj) {
+void Monitor::Inflate(Thread* self, mirror::Object* obj) {
DCHECK(self != NULL);
DCHECK(obj != NULL);
DCHECK_EQ(LW_SHAPE(*obj->GetRawLockWordAddress()), LW_SHAPE_THIN);
@@ -583,7 +585,7 @@
Runtime::Current()->GetMonitorList()->Add(m);
}
-void Monitor::MonitorEnter(Thread* self, Object* obj) {
+void Monitor::MonitorEnter(Thread* self, mirror::Object* obj) {
volatile int32_t* thinp = obj->GetRawLockWordAddress();
uint32_t sleepDelayNs;
uint32_t minSleepDelayNs = 1000000; /* 1 millisecond */
@@ -686,7 +688,7 @@
}
}
-bool Monitor::MonitorExit(Thread* self, Object* obj) {
+bool Monitor::MonitorExit(Thread* self, mirror::Object* obj) {
volatile int32_t* thinp = obj->GetRawLockWordAddress();
DCHECK(self != NULL);
@@ -748,7 +750,7 @@
/*
* Object.wait(). Also called for class init.
*/
-void Monitor::Wait(Thread* self, Object *obj, int64_t ms, int32_t ns,
+void Monitor::Wait(Thread* self, mirror::Object *obj, int64_t ms, int32_t ns,
bool interruptShouldThrow, ThreadState why) {
volatile int32_t* thinp = obj->GetRawLockWordAddress();
@@ -772,7 +774,7 @@
LW_MONITOR(*thinp)->Wait(self, ms, ns, interruptShouldThrow, why);
}
-void Monitor::Notify(Thread* self, Object *obj) {
+void Monitor::Notify(Thread* self, mirror::Object *obj) {
uint32_t thin = *obj->GetRawLockWordAddress();
// If the lock is still thin, there aren't any waiters;
@@ -791,7 +793,7 @@
}
}
-void Monitor::NotifyAll(Thread* self, Object *obj) {
+void Monitor::NotifyAll(Thread* self, mirror::Object *obj) {
uint32_t thin = *obj->GetRawLockWordAddress();
// If the lock is still thin, there aren't any waiters;
@@ -822,7 +824,7 @@
void Monitor::DescribeWait(std::ostream& os, const Thread* thread) {
ThreadState state = thread->GetState();
- Object* object = NULL;
+ mirror::Object* object = NULL;
uint32_t lock_owner = ThreadList::kInvalidId;
if (state == kWaiting || state == kTimedWaiting || state == kSleeping) {
if (state == kSleeping) {
@@ -860,10 +862,10 @@
os << "\n";
}
-Object* Monitor::GetContendedMonitor(Thread* thread) {
+mirror::Object* Monitor::GetContendedMonitor(Thread* thread) {
// This is used to implement JDWP's ThreadReference.CurrentContendedMonitor, and has a bizarre
// definition of contended that includes a monitor a thread is trying to enter...
- Object* result = thread->monitor_enter_object_;
+ mirror::Object* result = thread->monitor_enter_object_;
if (result != NULL) {
return result;
}
@@ -878,15 +880,16 @@
return NULL;
}
-void Monitor::VisitLocks(StackVisitor* stack_visitor, void (*callback)(Object*, void*), void* callback_context) {
- AbstractMethod* m = stack_visitor->GetMethod();
+void Monitor::VisitLocks(StackVisitor* stack_visitor, void (*callback)(mirror::Object*, void*),
+ void* callback_context) {
+ mirror::AbstractMethod* m = stack_visitor->GetMethod();
CHECK(m != NULL);
// Native methods are an easy special case.
// TODO: use the JNI implementation's table of explicit MonitorEnter calls and dump those too.
if (m->IsNative()) {
if (m->IsSynchronized()) {
- Object* jni_this = stack_visitor->GetCurrentSirt()->GetReference(0);
+ mirror::Object* jni_this = stack_visitor->GetCurrentSirt()->GetReference(0);
callback(jni_this, callback_context);
}
return;
@@ -933,13 +936,13 @@
}
uint16_t monitor_register = ((monitor_enter_instruction >> 8) & 0xff);
- Object* o = reinterpret_cast<Object*>(stack_visitor->GetVReg(m, monitor_register,
- kReferenceVReg));
+ mirror::Object* o = reinterpret_cast<mirror::Object*>(stack_visitor->GetVReg(m, monitor_register,
+ kReferenceVReg));
callback(o, callback_context);
}
}
-void Monitor::TranslateLocation(const AbstractMethod* method, uint32_t dex_pc,
+void Monitor::TranslateLocation(const mirror::AbstractMethod* method, uint32_t dex_pc,
const char*& source_file, uint32_t& line_number) const {
// If method is null, location is unknown
if (method == NULL) {
@@ -968,7 +971,7 @@
list_.push_front(m);
}
-void MonitorList::SweepMonitorList(Heap::IsMarkedTester is_marked, void* arg) {
+void MonitorList::SweepMonitorList(IsMarkedTester is_marked, void* arg) {
MutexLock mu(Thread::Current(), monitor_list_lock_);
typedef std::list<Monitor*>::iterator It; // TODO: C++0x auto
It it = list_.begin();
@@ -984,7 +987,7 @@
}
}
-MonitorInfo::MonitorInfo(Object* o) : owner(NULL), entry_count(0) {
+MonitorInfo::MonitorInfo(mirror::Object* o) : owner(NULL), entry_count(0) {
uint32_t lock_word = *o->GetRawLockWordAddress();
if (LW_SHAPE(lock_word) == LW_SHAPE_THIN) {
uint32_t owner_thin_lock_id = LW_LOCK_OWNER(lock_word);
diff --git a/src/monitor.h b/src/monitor.h
index 1b5ab76..9194c08 100644
--- a/src/monitor.h
+++ b/src/monitor.h
@@ -25,8 +25,8 @@
#include <vector>
#include "base/mutex.h"
-#include "heap.h"
-#include "thread.h"
+#include "root_visitor.h"
+#include "thread_state.h"
namespace art {
@@ -55,8 +55,10 @@
#define LW_LOCK_OWNER_SHIFT 3
#define LW_LOCK_OWNER(x) (((x) >> LW_LOCK_OWNER_SHIFT) & LW_LOCK_OWNER_MASK)
+namespace mirror {
class AbstractMethod;
class Object;
+} // namespace mirror
class Thread;
class StackVisitor;
@@ -70,18 +72,19 @@
static uint32_t GetThinLockId(uint32_t raw_lock_word)
NO_THREAD_SAFETY_ANALYSIS; // Reading lock owner without holding lock is racy.
- static void MonitorEnter(Thread* thread, Object* obj)
+ static void MonitorEnter(Thread* thread, mirror::Object* obj)
EXCLUSIVE_LOCK_FUNCTION(monitor_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static bool MonitorExit(Thread* thread, Object* obj)
+ static bool MonitorExit(Thread* thread, mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
UNLOCK_FUNCTION(monitor_lock_);
- static void Notify(Thread* self, Object* obj)
+ static void Notify(Thread* self, mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static void NotifyAll(Thread* self, Object* obj)
+ static void NotifyAll(Thread* self, mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static void Wait(Thread* self, Object* obj, int64_t ms, int32_t ns, bool interruptShouldThrow, ThreadState why)
+ static void Wait(Thread* self, mirror::Object* obj, int64_t ms, int32_t ns,
+ bool interruptShouldThrow, ThreadState why)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void DescribeWait(std::ostream& os, const Thread* thread)
@@ -89,30 +92,31 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Used to implement JDWP's ThreadReference.CurrentContendedMonitor.
- static Object* GetContendedMonitor(Thread* thread);
+ static mirror::Object* GetContendedMonitor(Thread* thread);
// Calls 'callback' once for each lock held in the single stack frame represented by
// the current state of 'stack_visitor'.
- static void VisitLocks(StackVisitor* stack_visitor, void (*callback)(Object*, void*), void* callback_context)
+ static void VisitLocks(StackVisitor* stack_visitor, void (*callback)(mirror::Object*, void*),
+ void* callback_context)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Object* GetObject();
+ mirror::Object* GetObject();
private:
- explicit Monitor(Thread* owner, Object* obj)
+ explicit Monitor(Thread* owner, mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void AppendToWaitSet(Thread* thread) EXCLUSIVE_LOCKS_REQUIRED(monitor_lock_);
void RemoveFromWaitSet(Thread* thread) EXCLUSIVE_LOCKS_REQUIRED(monitor_lock_);
- static void Inflate(Thread* self, Object* obj)
+ static void Inflate(Thread* self, mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void LogContentionEvent(Thread* self, uint32_t wait_ms, uint32_t sample_percent,
const char* owner_filename, uint32_t owner_line_number)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static void FailedUnlock(Object* obj, Thread* expected_owner, Thread* found_owner, Monitor* mon)
+ static void FailedUnlock(mirror::Object* obj, Thread* expected_owner, Thread* found_owner, Monitor* mon)
LOCKS_EXCLUDED(Locks::thread_list_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -137,7 +141,7 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Translates the provided method and pc into its declaring class' source file and line number.
- void TranslateLocation(const AbstractMethod* method, uint32_t pc,
+ void TranslateLocation(const mirror::AbstractMethod* method, uint32_t pc,
const char*& source_file, uint32_t& line_number) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -153,7 +157,7 @@
int lock_count_ GUARDED_BY(monitor_lock_);
// What object are we part of (for debugging).
- Object* const obj_;
+ mirror::Object* const obj_;
// Threads currently waiting on this monitor.
Thread* wait_set_ GUARDED_BY(monitor_lock_);
@@ -161,12 +165,12 @@
// Method and dex pc where the lock owner acquired the lock, used when lock
// sampling is enabled. locking_method_ may be null if the lock is currently
// unlocked, or if the lock is acquired by the system when the stack is empty.
- const AbstractMethod* locking_method_ GUARDED_BY(monitor_lock_);
+ const mirror::AbstractMethod* locking_method_ GUARDED_BY(monitor_lock_);
uint32_t locking_dex_pc_ GUARDED_BY(monitor_lock_);
friend class MonitorInfo;
friend class MonitorList;
- friend class Object;
+ friend class mirror::Object;
DISALLOW_COPY_AND_ASSIGN(Monitor);
};
@@ -177,7 +181,7 @@
void Add(Monitor* m);
- void SweepMonitorList(Heap::IsMarkedTester is_marked, void* arg)
+ void SweepMonitorList(IsMarkedTester is_marked, void* arg)
SHARED_LOCKS_REQUIRED(Locks::heap_bitmap_lock_);
private:
@@ -192,7 +196,7 @@
// For use only by the JDWP implementation.
class MonitorInfo {
public:
- MonitorInfo(Object* o) EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_);
+ MonitorInfo(mirror::Object* o) EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_);
Thread* owner;
size_t entry_count;
diff --git a/src/monitor_android.cc b/src/monitor_android.cc
index 6e22237..d3ac143 100644
--- a/src/monitor_android.cc
+++ b/src/monitor_android.cc
@@ -15,7 +15,6 @@
*/
#include "monitor.h"
-#include "object.h"
#include "thread.h"
#include <fcntl.h>
@@ -79,7 +78,7 @@
// Emit the source code file name, <= 37 bytes.
uintptr_t pc;
- AbstractMethod* m = self->GetCurrentMethod(&pc);
+ mirror::AbstractMethod* m = self->GetCurrentMethod(&pc);
const char* filename;
uint32_t line_number;
TranslateLocation(m, pc, filename, line_number);
diff --git a/src/native/dalvik_system_DexFile.cc b/src/native/dalvik_system_DexFile.cc
index 7485600..e549a8b 100644
--- a/src/native/dalvik_system_DexFile.cc
+++ b/src/native/dalvik_system_DexFile.cc
@@ -18,11 +18,12 @@
#include "base/logging.h"
#include "class_linker.h"
-#include "class_loader.h"
#include "dex_file.h"
#include "gc/space.h"
#include "image.h"
#include "jni_internal.h"
+#include "mirror/class_loader.h"
+#include "mirror/string.h"
#include "oat.h"
#include "os.h"
#include "runtime.h"
@@ -150,9 +151,8 @@
}
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
class_linker->RegisterDexFile(*dex_file);
- Object* class_loader_object = soa.Decode<Object*>(javaLoader);
- ClassLoader* class_loader = down_cast<ClassLoader*>(class_loader_object);
- Class* result = class_linker->DefineClass(descriptor, class_loader, *dex_file, *dex_class_def);
+ mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(javaLoader);
+ mirror::Class* result = class_linker->DefineClass(descriptor, class_loader, *dex_file, *dex_class_def);
return soa.AddLocalReference<jclass>(result);
}
diff --git a/src/native/dalvik_system_VMDebug.cc b/src/native/dalvik_system_VMDebug.cc
index e5a398a..dc07a31 100644
--- a/src/native/dalvik_system_VMDebug.cc
+++ b/src/native/dalvik_system_VMDebug.cc
@@ -21,6 +21,7 @@
#include "debugger.h"
#include "hprof/hprof.h"
#include "jni_internal.h"
+#include "mirror/class.h"
#include "ScopedUtfChars.h"
#include "scoped_thread_state_change.h"
#include "toStringArray.h"
@@ -220,11 +221,11 @@
static jlong VMDebug_countInstancesOfClass(JNIEnv* env, jclass, jclass javaClass,
jboolean countAssignable) {
ScopedObjectAccess soa(env);
- Class* c = soa.Decode<Class*>(javaClass);
+ mirror::Class* c = soa.Decode<mirror::Class*>(javaClass);
if (c == NULL) {
return 0;
}
- std::vector<Class*> classes;
+ std::vector<mirror::Class*> classes;
classes.push_back(c);
uint64_t count = 0;
Runtime::Current()->GetHeap()->CountInstances(classes, countAssignable, &count);
diff --git a/src/native/dalvik_system_VMRuntime.cc b/src/native/dalvik_system_VMRuntime.cc
index bf518dc..5ce27fb 100644
--- a/src/native/dalvik_system_VMRuntime.cc
+++ b/src/native/dalvik_system_VMRuntime.cc
@@ -19,7 +19,8 @@
#include "class_linker.h"
#include "debugger.h"
#include "jni_internal.h"
-#include "object.h"
+#include "mirror/object.h"
+#include "mirror/object-inl.h"
#include "object_utils.h"
#include "scoped_thread_state_change.h"
#include "gc/space.h"
@@ -52,7 +53,7 @@
UNIMPLEMENTED(FATAL);
#endif
- Class* element_class = soa.Decode<Class*>(javaElementClass);
+ mirror::Class* element_class = soa.Decode<mirror::Class*>(javaElementClass);
if (element_class == NULL) {
soa.Self()->ThrowNewException("Ljava/lang/NullPointerException;", "element class == null");
return NULL;
@@ -66,8 +67,8 @@
std::string descriptor;
descriptor += "[";
descriptor += ClassHelper(element_class).GetDescriptor();
- Class* array_class = class_linker->FindClass(descriptor.c_str(), NULL);
- Array* result = Array::Alloc(soa.Self(), array_class, length);
+ mirror::Class* array_class = class_linker->FindClass(descriptor.c_str(), NULL);
+ mirror::Array* result = mirror::Array::Alloc(soa.Self(), array_class, length);
if (result == NULL) {
return NULL;
}
@@ -79,7 +80,7 @@
return 0;
}
ScopedObjectAccess soa(env);
- Array* array = soa.Decode<Array*>(javaArray);
+ mirror::Array* array = soa.Decode<mirror::Array*>(javaArray);
if (!array->IsArrayInstance()) {
soa.Self()->ThrowNewException("Ljava/lang/IllegalArgumentException;", "not an array");
return 0;
diff --git a/src/native/dalvik_system_VMStack.cc b/src/native/dalvik_system_VMStack.cc
index 494f38d..bb2ed88 100644
--- a/src/native/dalvik_system_VMStack.cc
+++ b/src/native/dalvik_system_VMStack.cc
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-#include "class_loader.h"
#include "jni_internal.h"
#include "nth_caller_visitor.h"
-#include "object.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/class.h"
+#include "mirror/class_loader.h"
#include "scoped_thread_state_change.h"
#include "thread_list.h"
@@ -26,7 +27,7 @@
static jobject GetThreadStack(JNIEnv* env, jobject peer) {
{
ScopedObjectAccess soa(env);
- if (soa.Decode<Object*>(peer) == soa.Self()->GetPeer()) {
+ if (soa.Decode<mirror::Object*>(peer) == soa.Self()->GetPeer()) {
return soa.Self()->CreateInternalStackTrace(soa);
}
}
@@ -73,13 +74,13 @@
static jobject VMStack_getClosestUserClassLoader(JNIEnv* env, jclass, jobject javaBootstrap,
jobject javaSystem) {
struct ClosestUserClassLoaderVisitor : public StackVisitor {
- ClosestUserClassLoaderVisitor(Thread* thread, Object* bootstrap, Object* system)
+ ClosestUserClassLoaderVisitor(Thread* thread, mirror::Object* bootstrap, mirror::Object* system)
: StackVisitor(thread, NULL), bootstrap(bootstrap), system(system), class_loader(NULL) {}
bool VisitFrame() {
DCHECK(class_loader == NULL);
- Class* c = GetMethod()->GetDeclaringClass();
- Object* cl = c->GetClassLoader();
+ mirror::Class* c = GetMethod()->GetDeclaringClass();
+ mirror::Object* cl = c->GetClassLoader();
if (cl != NULL && cl != bootstrap && cl != system) {
class_loader = cl;
return false;
@@ -87,13 +88,13 @@
return true;
}
- Object* bootstrap;
- Object* system;
- Object* class_loader;
+ mirror::Object* bootstrap;
+ mirror::Object* system;
+ mirror::Object* class_loader;
};
ScopedObjectAccess soa(env);
- Object* bootstrap = soa.Decode<Object*>(javaBootstrap);
- Object* system = soa.Decode<Object*>(javaSystem);
+ mirror::Object* bootstrap = soa.Decode<mirror::Object*>(javaBootstrap);
+ mirror::Object* system = soa.Decode<mirror::Object*>(javaSystem);
ClosestUserClassLoaderVisitor visitor(soa.Self(), bootstrap, system);
visitor.WalkStack();
return soa.AddLocalReference<jobject>(visitor.class_loader);
diff --git a/src/native/java_lang_Class.cc b/src/native/java_lang_Class.cc
index 59c9bef..dded787 100644
--- a/src/native/java_lang_Class.cc
+++ b/src/native/java_lang_Class.cc
@@ -15,10 +15,12 @@
*/
#include "class_linker.h"
-#include "class_loader.h"
#include "jni_internal.h"
#include "nth_caller_visitor.h"
-#include "object.h"
+#include "mirror/class.h"
+#include "mirror/class_loader.h"
+#include "mirror/object-inl.h"
+#include "mirror/proxy.h"
#include "object_utils.h"
#include "scoped_thread_state_change.h"
#include "ScopedLocalRef.h"
@@ -27,9 +29,9 @@
namespace art {
-static Class* DecodeClass(const ScopedObjectAccess& soa, jobject java_class)
+static mirror::Class* DecodeClass(const ScopedObjectAccess& soa, jobject java_class)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Class* c = soa.Decode<Class*>(java_class);
+ mirror::Class* c = soa.Decode<mirror::Class*>(java_class);
DCHECK(c != NULL);
DCHECK(c->IsClass());
// TODO: we could EnsureInitialized here, rather than on every reflective get/set or invoke .
@@ -56,9 +58,9 @@
}
std::string descriptor(DotToDescriptor(name.c_str()));
- ClassLoader* class_loader = soa.Decode<ClassLoader*>(javaLoader);
+ mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(javaLoader);
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Class* c = class_linker->FindClass(descriptor.c_str(), class_loader);
+ mirror::Class* c = class_linker->FindClass(descriptor.c_str(), class_loader);
if (c == NULL) {
ScopedLocalRef<jthrowable> cause(env, env->ExceptionOccurred());
env->ExceptionClear();
@@ -76,7 +78,7 @@
static jint Class_getAnnotationDirectoryOffset(JNIEnv* env, jclass javaClass) {
ScopedObjectAccess soa(env);
- Class* c = DecodeClass(soa, javaClass);
+ mirror::Class* c = DecodeClass(soa, javaClass);
if (c->IsPrimitive() || c->IsArrayClass() || c->IsProxyClass()) {
return 0; // primitive, array and proxy classes don't have class definitions
}
@@ -90,9 +92,9 @@
static jobject Class_getDex(JNIEnv* env, jobject javaClass) {
ScopedObjectAccess soa(env);
- Class* c = DecodeClass(soa, javaClass);
+ mirror::Class* c = DecodeClass(soa, javaClass);
- DexCache* dex_cache = c->GetDexCache();
+ mirror::DexCache* dex_cache = c->GetDexCache();
if (dex_cache == NULL) {
return NULL;
}
@@ -105,13 +107,14 @@
static jstring Class_getNameNative(JNIEnv* env, jobject javaThis) {
ScopedObjectAccess soa(env);
- Class* c = DecodeClass(soa, javaThis);
+ mirror::Class* c = DecodeClass(soa, javaThis);
return soa.AddLocalReference<jstring>(c->ComputeName());
}
static jobjectArray Class_getProxyInterfaces(JNIEnv* env, jobject javaThis) {
ScopedObjectAccess soa(env);
- SynthesizedProxyClass* c = down_cast<SynthesizedProxyClass*>(DecodeClass(soa, javaThis));
+ mirror::SynthesizedProxyClass* c =
+ down_cast<mirror::SynthesizedProxyClass*>(DecodeClass(soa, javaThis));
return soa.AddLocalReference<jobjectArray>(c->GetInterfaces()->Clone(soa.Self()));
}
diff --git a/src/native/java_lang_Object.cc b/src/native/java_lang_Object.cc
index f3c295e..75d5f70 100644
--- a/src/native/java_lang_Object.cc
+++ b/src/native/java_lang_Object.cc
@@ -15,7 +15,7 @@
*/
#include "jni_internal.h"
-#include "object.h"
+#include "mirror/object.h"
#include "scoped_thread_state_change.h"
// TODO: better support for overloading.
@@ -27,31 +27,31 @@
static jobject Object_internalClone(JNIEnv* env, jobject java_this) {
ScopedObjectAccess soa(env);
- Object* o = soa.Decode<Object*>(java_this);
+ mirror::Object* o = soa.Decode<mirror::Object*>(java_this);
return soa.AddLocalReference<jobject>(o->Clone(soa.Self()));
}
static void Object_notify(JNIEnv* env, jobject java_this) {
ScopedObjectAccess soa(env);
- Object* o = soa.Decode<Object*>(java_this);
+ mirror::Object* o = soa.Decode<mirror::Object*>(java_this);
o->Notify();
}
static void Object_notifyAll(JNIEnv* env, jobject java_this) {
ScopedObjectAccess soa(env);
- Object* o = soa.Decode<Object*>(java_this);
+ mirror::Object* o = soa.Decode<mirror::Object*>(java_this);
o->NotifyAll();
}
static void Object_wait(JNIEnv* env, jobject java_this) {
ScopedObjectAccess soa(env);
- Object* o = soa.Decode<Object*>(java_this);
+ mirror::Object* o = soa.Decode<mirror::Object*>(java_this);
o->Wait();
}
static void Object_waitJI(JNIEnv* env, jobject java_this, jlong ms, jint ns) {
ScopedObjectAccess soa(env);
- Object* o = soa.Decode<Object*>(java_this);
+ mirror::Object* o = soa.Decode<mirror::Object*>(java_this);
o->Wait(ms, ns);
}
diff --git a/src/native/java_lang_Runtime.cc b/src/native/java_lang_Runtime.cc
index d197b73..54ccddc 100644
--- a/src/native/java_lang_Runtime.cc
+++ b/src/native/java_lang_Runtime.cc
@@ -18,10 +18,9 @@
#include <limits.h>
#include <unistd.h>
-#include "class_loader.h"
#include "heap.h"
#include "jni_internal.h"
-#include "object.h"
+#include "mirror/class_loader.h"
#include "runtime.h"
#include "scoped_thread_state_change.h"
#include "ScopedUtfChars.h"
@@ -59,7 +58,7 @@
}
}
- ClassLoader* classLoader = soa.Decode<ClassLoader*>(javaLoader);
+ mirror::ClassLoader* classLoader = soa.Decode<mirror::ClassLoader*>(javaLoader);
std::string detail;
JavaVMExt* vm = Runtime::Current()->GetJavaVM();
bool success = vm->LoadNativeLibrary(filename.c_str(), classLoader, detail);
diff --git a/src/native/java_lang_String.cc b/src/native/java_lang_String.cc
index 8b7a691..44ab1ca 100644
--- a/src/native/java_lang_String.cc
+++ b/src/native/java_lang_String.cc
@@ -15,7 +15,7 @@
*/
#include "jni_internal.h"
-#include "object.h"
+#include "mirror/string.h"
#include "scoped_thread_state_change.h"
#include "ScopedLocalRef.h"
@@ -28,7 +28,7 @@
return -1;
} else {
ScopedObjectAccess soa(env);
- return soa.Decode<String*>(javaThis)->CompareTo(soa.Decode<String*>(javaRhs));
+ return soa.Decode<mirror::String*>(javaThis)->CompareTo(soa.Decode<mirror::String*>(javaRhs));
}
}
@@ -37,14 +37,14 @@
// This method does not handle supplementary characters. They're dealt with in managed code.
DCHECK_LE(ch, 0xffff);
- String* s = soa.Decode<String*>(java_this);
+ mirror::String* s = soa.Decode<mirror::String*>(java_this);
return s->FastIndexOf(ch, start);
}
static jstring String_intern(JNIEnv* env, jobject javaThis) {
ScopedObjectAccess soa(env);
- String* s = soa.Decode<String*>(javaThis);
- String* result = s->Intern();
+ mirror::String* s = soa.Decode<mirror::String*>(javaThis);
+ mirror::String* result = s->Intern();
return soa.AddLocalReference<jstring>(result);
}
diff --git a/src/native/java_lang_System.cc b/src/native/java_lang_System.cc
index d74c9db..54ee2e9 100644
--- a/src/native/java_lang_System.cc
+++ b/src/native/java_lang_System.cc
@@ -14,8 +14,12 @@
* limitations under the License.
*/
+#include "gc/card_table-inl.h"
#include "jni_internal.h"
-#include "object.h"
+#include "mirror/array.h"
+#include "mirror/class.h"
+#include "mirror/class-inl.h"
+#include "mirror/object-inl.h"
#include "scoped_thread_state_change.h"
/*
@@ -101,7 +105,7 @@
namespace art {
-static void ThrowArrayStoreException_NotAnArray(const char* identifier, Object* array)
+static void ThrowArrayStoreException_NotAnArray(const char* identifier, mirror::Object* array)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::string actualType(PrettyTypeOf(array));
Thread::Current()->ThrowNewExceptionF("Ljava/lang/ArrayStoreException;",
@@ -122,8 +126,8 @@
}
// Make sure source and destination are both arrays.
- Object* srcObject = soa.Decode<Object*>(javaSrc);
- Object* dstObject = soa.Decode<Object*>(javaDst);
+ mirror::Object* srcObject = soa.Decode<mirror::Object*>(javaSrc);
+ mirror::Object* dstObject = soa.Decode<mirror::Object*>(javaDst);
if (!srcObject->IsArrayInstance()) {
ThrowArrayStoreException_NotAnArray("source", srcObject);
return;
@@ -132,10 +136,10 @@
ThrowArrayStoreException_NotAnArray("destination", dstObject);
return;
}
- Array* srcArray = srcObject->AsArray();
- Array* dstArray = dstObject->AsArray();
- Class* srcComponentType = srcArray->GetClass()->GetComponentType();
- Class* dstComponentType = dstArray->GetClass()->GetComponentType();
+ mirror::Array* srcArray = srcObject->AsArray();
+ mirror::Array* dstArray = dstObject->AsArray();
+ mirror::Class* srcComponentType = srcArray->GetClass()->GetComponentType();
+ mirror::Class* dstComponentType = dstArray->GetClass()->GetComponentType();
// Bounds checking.
if (srcPos < 0 || dstPos < 0 || length < 0 || srcPos > srcArray->GetLength() - length || dstPos > dstArray->GetLength() - length) {
@@ -182,7 +186,7 @@
}
// Neither class is primitive. Are the types trivially compatible?
- const size_t width = sizeof(Object*);
+ const size_t width = sizeof(mirror::Object*);
uint8_t* dstBytes = reinterpret_cast<uint8_t*>(dstArray->GetRawData(width));
const uint8_t* srcBytes = reinterpret_cast<const uint8_t*>(srcArray->GetRawData(width));
if (dstArray == srcArray || dstComponentType->IsAssignableFrom(srcComponentType)) {
@@ -202,20 +206,21 @@
// We already dealt with overlapping copies, so we don't need to cope with that case below.
CHECK_NE(dstArray, srcArray);
- Object* const * srcObjects = reinterpret_cast<Object* const *>(srcBytes + srcPos * width);
- Object** dstObjects = reinterpret_cast<Object**>(dstBytes + dstPos * width);
- Class* dstClass = dstArray->GetClass()->GetComponentType();
+ mirror::Object* const * srcObjects =
+ reinterpret_cast<mirror::Object* const *>(srcBytes + srcPos * width);
+ mirror::Object** dstObjects = reinterpret_cast<mirror::Object**>(dstBytes + dstPos * width);
+ mirror::Class* dstClass = dstArray->GetClass()->GetComponentType();
// We want to avoid redundant IsAssignableFrom checks where possible, so we cache a class that
// we know is assignable to the destination array's component type.
- Class* lastAssignableElementClass = dstClass;
+ mirror::Class* lastAssignableElementClass = dstClass;
- Object* o = NULL;
+ mirror::Object* o = NULL;
int i = 0;
for (; i < length; ++i) {
o = srcObjects[i];
if (o != NULL) {
- Class* oClass = o->GetClass();
+ mirror::Class* oClass = o->GetClass();
if (lastAssignableElementClass == oClass) {
dstObjects[i] = o;
} else if (dstClass->IsAssignableFrom(oClass)) {
@@ -243,7 +248,7 @@
static jint System_identityHashCode(JNIEnv* env, jclass, jobject javaObject) {
ScopedObjectAccess soa(env);
- Object* o = soa.Decode<Object*>(javaObject);
+ mirror::Object* o = soa.Decode<mirror::Object*>(javaObject);
return static_cast<jint>(o->IdentityHashCode());
}
diff --git a/src/native/java_lang_Thread.cc b/src/native/java_lang_Thread.cc
index 473369e..ca4be9d 100644
--- a/src/native/java_lang_Thread.cc
+++ b/src/native/java_lang_Thread.cc
@@ -17,7 +17,7 @@
#include "debugger.h"
#include "jni_internal.h"
#include "monitor.h"
-#include "object.h"
+#include "mirror/object.h"
#include "scoped_thread_state_change.h"
#include "ScopedUtfChars.h"
#include "thread.h"
@@ -88,7 +88,7 @@
static jboolean Thread_nativeHoldsLock(JNIEnv* env, jobject java_thread, jobject java_object) {
ScopedObjectAccess soa(env);
- Object* object = soa.Decode<Object*>(java_object);
+ mirror::Object* object = soa.Decode<mirror::Object*>(java_object);
if (object == NULL) {
Thread::Current()->ThrowNewException("Ljava/lang/NullPointerException;", "object == null");
return JNI_FALSE;
@@ -111,7 +111,7 @@
ScopedUtfChars name(env, java_name);
{
ScopedObjectAccess soa(env);
- if (soa.Decode<Object*>(peer) == soa.Self()->GetPeer()) {
+ if (soa.Decode<mirror::Object*>(peer) == soa.Self()->GetPeer()) {
soa.Self()->SetThreadName(name.c_str());
return;
}
@@ -149,7 +149,7 @@
static void Thread_sleep(JNIEnv* env, jclass, jobject java_lock, jlong ms, jint ns) {
ScopedObjectAccess soa(env);
- Object* lock = soa.Decode<Object*>(java_lock);
+ mirror::Object* lock = soa.Decode<mirror::Object*>(java_lock);
Monitor::Wait(Thread::Current(), lock, ms, ns, true, kSleeping);
}
diff --git a/src/native/java_lang_VMClassLoader.cc b/src/native/java_lang_VMClassLoader.cc
index 4b5c31c..02b7c25 100644
--- a/src/native/java_lang_VMClassLoader.cc
+++ b/src/native/java_lang_VMClassLoader.cc
@@ -15,8 +15,8 @@
*/
#include "class_linker.h"
-#include "class_loader.h"
#include "jni_internal.h"
+#include "mirror/class_loader.h"
#include "scoped_thread_state_change.h"
#include "ScopedUtfChars.h"
#include "zip_archive.h"
@@ -25,14 +25,14 @@
static jclass VMClassLoader_findLoadedClass(JNIEnv* env, jclass, jobject javaLoader, jstring javaName) {
ScopedObjectAccess soa(env);
- ClassLoader* loader = soa.Decode<ClassLoader*>(javaLoader);
+ mirror::ClassLoader* loader = soa.Decode<mirror::ClassLoader*>(javaLoader);
ScopedUtfChars name(env, javaName);
if (name.c_str() == NULL) {
return NULL;
}
std::string descriptor(DotToDescriptor(name.c_str()));
- Class* c = Runtime::Current()->GetClassLinker()->LookupClass(descriptor.c_str(), loader);
+ mirror::Class* c = Runtime::Current()->GetClassLinker()->LookupClass(descriptor.c_str(), loader);
if (c != NULL && c->IsResolved()) {
return soa.AddLocalReference<jclass>(c);
} else {
diff --git a/src/native/java_lang_reflect_Array.cc b/src/native/java_lang_reflect_Array.cc
index 15aeed2..2833cb0 100644
--- a/src/native/java_lang_reflect_Array.cc
+++ b/src/native/java_lang_reflect_Array.cc
@@ -16,7 +16,8 @@
#include "class_linker.h"
#include "jni_internal.h"
-#include "object.h"
+#include "mirror/class.h"
+#include "mirror/object-inl.h"
#include "object_utils.h"
#include "scoped_thread_state_change.h"
#include "sirt_ref.h"
@@ -26,21 +27,21 @@
static jobject Array_createMultiArray(JNIEnv* env, jclass, jclass javaElementClass, jobject javaDimArray) {
ScopedObjectAccess soa(env);
DCHECK(javaElementClass != NULL);
- Class* element_class = soa.Decode<Class*>(javaElementClass);
+ mirror::Class* element_class = soa.Decode<mirror::Class*>(javaElementClass);
DCHECK(element_class->IsClass());
DCHECK(javaDimArray != NULL);
- Object* dimensions_obj = soa.Decode<Object*>(javaDimArray);
+ mirror::Object* dimensions_obj = soa.Decode<mirror::Object*>(javaDimArray);
DCHECK(dimensions_obj->IsArrayInstance());
DCHECK_STREQ(ClassHelper(dimensions_obj->GetClass()).GetDescriptor(), "[I");
- IntArray* dimensions_array = down_cast<IntArray*>(dimensions_obj);
- Array* new_array = Array::CreateMultiArray(soa.Self(), element_class, dimensions_array);
+ mirror::IntArray* dimensions_array = down_cast<mirror::IntArray*>(dimensions_obj);
+ mirror::Array* new_array = mirror::Array::CreateMultiArray(soa.Self(), element_class, dimensions_array);
return soa.AddLocalReference<jobject>(new_array);
}
static jobject Array_createObjectArray(JNIEnv* env, jclass, jclass javaElementClass, jint length) {
ScopedObjectAccess soa(env);
DCHECK(javaElementClass != NULL);
- Class* element_class = soa.Decode<Class*>(javaElementClass);
+ mirror::Class* element_class = soa.Decode<mirror::Class*>(javaElementClass);
if (UNLIKELY(length < 0)) {
soa.Self()->ThrowNewExceptionF("Ljava/lang/NegativeArraySizeException;", "%d", length);
return NULL;
@@ -49,13 +50,13 @@
descriptor += ClassHelper(element_class).GetDescriptor();
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Class* array_class = class_linker->FindClass(descriptor.c_str(), element_class->GetClassLoader());
+ mirror::Class* array_class = class_linker->FindClass(descriptor.c_str(), element_class->GetClassLoader());
if (UNLIKELY(array_class == NULL)) {
CHECK(soa.Self()->IsExceptionPending());
return NULL;
}
DCHECK(array_class->IsArrayClass());
- Array* new_array = Array::Alloc(soa.Self(), array_class, length);
+ mirror::Array* new_array = mirror::Array::Alloc(soa.Self(), array_class, length);
return soa.AddLocalReference<jobject>(new_array);
}
diff --git a/src/native/java_lang_reflect_Constructor.cc b/src/native/java_lang_reflect_Constructor.cc
index ed0d1f1..fb84dfd 100644
--- a/src/native/java_lang_reflect_Constructor.cc
+++ b/src/native/java_lang_reflect_Constructor.cc
@@ -16,7 +16,10 @@
#include "class_linker.h"
#include "jni_internal.h"
-#include "object.h"
+#include "mirror/class-inl.h"
+#include "mirror/abstract_method.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object-inl.h"
#include "object_utils.h"
#include "reflection.h"
#include "scoped_thread_state_change.h"
@@ -32,8 +35,8 @@
*/
static jobject Constructor_newInstance(JNIEnv* env, jobject javaMethod, jobjectArray javaArgs) {
ScopedObjectAccess soa(env);
- AbstractMethod* m = soa.Decode<Object*>(javaMethod)->AsMethod();
- Class* c = m->GetDeclaringClass();
+ mirror::AbstractMethod* m = soa.Decode<mirror::Object*>(javaMethod)->AsMethod();
+ mirror::Class* c = m->GetDeclaringClass();
if (c->IsAbstract()) {
soa.Self()->ThrowNewExceptionF("Ljava/lang/InstantiationException;",
"Can't instantiate abstract class %s", PrettyDescriptor(c).c_str());
@@ -45,7 +48,7 @@
return NULL;
}
- Object* receiver = c->AllocObject(soa.Self());
+ mirror::Object* receiver = c->AllocObject(soa.Self());
if (receiver == NULL) {
return NULL;
}
diff --git a/src/native/java_lang_reflect_Field.cc b/src/native/java_lang_reflect_Field.cc
index fde8f94..9a2671c 100644
--- a/src/native/java_lang_reflect_Field.cc
+++ b/src/native/java_lang_reflect_Field.cc
@@ -15,15 +15,17 @@
*/
#include "class_linker.h"
+#include "class_linker-inl.h"
#include "jni_internal.h"
-#include "object.h"
+#include "mirror/field.h"
+#include "mirror/field-inl.h"
#include "object_utils.h"
#include "reflection.h"
#include "scoped_thread_state_change.h"
namespace art {
-static bool GetFieldValue(const ScopedObjectAccess& soa, Object* o, Field* f,
+static bool GetFieldValue(const ScopedObjectAccess& soa, mirror::Object* o, mirror::Field* f,
JValue& value, bool allow_references)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK_EQ(value.GetJ(), 0LL);
@@ -72,16 +74,16 @@
return false;
}
-static bool CheckReceiver(const ScopedObjectAccess& soa, jobject javaObj, Field* f,
- Object*& o)
+static bool CheckReceiver(const ScopedObjectAccess& soa, jobject javaObj, mirror::Field* f,
+ mirror::Object*& o)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (f->IsStatic()) {
o = f->GetDeclaringClass();
return true;
}
- o = soa.Decode<Object*>(javaObj);
- Class* declaringClass = f->GetDeclaringClass();
+ o = soa.Decode<mirror::Object*>(javaObj);
+ mirror::Class* declaringClass = f->GetDeclaringClass();
if (!VerifyObjectInClass(o, declaringClass)) {
return false;
}
@@ -90,8 +92,8 @@
static jobject Field_get(JNIEnv* env, jobject javaField, jobject javaObj) {
ScopedObjectAccess soa(env);
- Field* f = soa.DecodeField(env->FromReflectedField(javaField));
- Object* o = NULL;
+ mirror::Field* f = soa.DecodeField(env->FromReflectedField(javaField));
+ mirror::Object* o = NULL;
if (!CheckReceiver(soa, javaObj, f, o)) {
return NULL;
}
@@ -107,8 +109,8 @@
static JValue GetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char dst_descriptor) {
ScopedObjectAccess soa(env);
- Field* f = soa.DecodeField(env->FromReflectedField(javaField));
- Object* o = NULL;
+ mirror::Field* f = soa.DecodeField(env->FromReflectedField(javaField));
+ mirror::Object* o = NULL;
if (!CheckReceiver(soa, javaObj, f, o)) {
return JValue();
}
@@ -121,7 +123,7 @@
// Widen it if necessary (and possible).
JValue wide_value;
- Class* dst_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(dst_descriptor);
+ mirror::Class* dst_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(dst_descriptor);
if (!ConvertPrimitiveValue(FieldHelper(f).GetTypeAsPrimitiveType(), dst_type->GetPrimitiveType(),
field_value, wide_value)) {
return JValue();
@@ -161,7 +163,8 @@
return GetPrimitiveField(env, javaField, javaObj, 'S').GetS();
}
-static void SetFieldValue(Object* o, Field* f, const JValue& new_value, bool allow_references)
+static void SetFieldValue(mirror::Object* o, mirror::Field* f, const JValue& new_value,
+ bool allow_references)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(f->GetDeclaringClass(),
true, true)) {
@@ -214,17 +217,17 @@
static void Field_set(JNIEnv* env, jobject javaField, jobject javaObj, jobject javaValue) {
ScopedObjectAccess soa(env);
- Field* f = soa.DecodeField(env->FromReflectedField(javaField));
+ mirror::Field* f = soa.DecodeField(env->FromReflectedField(javaField));
// Unbox the value, if necessary.
- Object* boxed_value = soa.Decode<Object*>(javaValue);
+ mirror::Object* boxed_value = soa.Decode<mirror::Object*>(javaValue);
JValue unboxed_value;
if (!UnboxPrimitiveForField(boxed_value, FieldHelper(f).GetType(), unboxed_value, f)) {
return;
}
// Check that the receiver is non-null and an instance of the field's declaring class.
- Object* o = NULL;
+ mirror::Object* o = NULL;
if (!CheckReceiver(soa, javaObj, f, o)) {
return;
}
@@ -235,8 +238,8 @@
static void SetPrimitiveField(JNIEnv* env, jobject javaField, jobject javaObj, char src_descriptor,
const JValue& new_value) {
ScopedObjectAccess soa(env);
- Field* f = soa.DecodeField(env->FromReflectedField(javaField));
- Object* o = NULL;
+ mirror::Field* f = soa.DecodeField(env->FromReflectedField(javaField));
+ mirror::Object* o = NULL;
if (!CheckReceiver(soa, javaObj, f, o)) {
return;
}
@@ -249,7 +252,7 @@
// Widen the value if necessary (and possible).
JValue wide_value;
- Class* src_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(src_descriptor);
+ mirror::Class* src_type = Runtime::Current()->GetClassLinker()->FindPrimitiveClass(src_descriptor);
if (!ConvertPrimitiveValue(src_type->GetPrimitiveType(), fh.GetTypeAsPrimitiveType(),
new_value, wide_value)) {
return;
diff --git a/src/native/java_lang_reflect_Method.cc b/src/native/java_lang_reflect_Method.cc
index b1eb6e0..14dc6a4 100644
--- a/src/native/java_lang_reflect_Method.cc
+++ b/src/native/java_lang_reflect_Method.cc
@@ -16,7 +16,12 @@
#include "class_linker.h"
#include "jni_internal.h"
-#include "object.h"
+#include "mirror/class-inl.h"
+#include "mirror/abstract_method.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
+#include "mirror/proxy.h"
#include "object_utils.h"
#include "reflection.h"
#include "scoped_thread_state_change.h"
@@ -30,10 +35,10 @@
static jobject Method_getExceptionTypesNative(JNIEnv* env, jobject javaMethod) {
ScopedObjectAccess soa(env);
- AbstractMethod* proxy_method = soa.Decode<Object*>(javaMethod)->AsMethod();
+ mirror::AbstractMethod* proxy_method = soa.Decode<mirror::Object*>(javaMethod)->AsMethod();
CHECK(proxy_method->GetDeclaringClass()->IsProxyClass());
- SynthesizedProxyClass* proxy_class =
- down_cast<SynthesizedProxyClass*>(proxy_method->GetDeclaringClass());
+ mirror::SynthesizedProxyClass* proxy_class =
+ down_cast<mirror::SynthesizedProxyClass*>(proxy_method->GetDeclaringClass());
int throws_index = -1;
size_t num_virt_methods = proxy_class->NumVirtualMethods();
for (size_t i = 0; i < num_virt_methods; i++) {
@@ -43,13 +48,13 @@
}
}
CHECK_NE(throws_index, -1);
- ObjectArray<Class>* declared_exceptions = proxy_class->GetThrows()->Get(throws_index);
+ mirror::ObjectArray<mirror::Class>* declared_exceptions = proxy_class->GetThrows()->Get(throws_index);
return soa.AddLocalReference<jobject>(declared_exceptions->Clone(soa.Self()));
}
static jobject Method_findOverriddenMethodNative(JNIEnv* env, jobject javaMethod) {
ScopedObjectAccess soa(env);
- AbstractMethod* method = soa.Decode<Object*>(javaMethod)->AsMethod();
+ mirror::AbstractMethod* method = soa.Decode<mirror::Object*>(javaMethod)->AsMethod();
return soa.AddLocalReference<jobject>(method->FindOverriddenMethod());
}
diff --git a/src/native/java_lang_reflect_Proxy.cc b/src/native/java_lang_reflect_Proxy.cc
index a567268..547ce7b 100644
--- a/src/native/java_lang_reflect_Proxy.cc
+++ b/src/native/java_lang_reflect_Proxy.cc
@@ -15,22 +15,28 @@
*/
#include "class_linker.h"
-#include "class_loader.h"
#include "jni_internal.h"
-#include "object.h"
+#include "mirror/class_loader.h"
+#include "mirror/object_array.h"
+#include "mirror/string.h"
#include "scoped_thread_state_change.h"
namespace art {
-static jclass Proxy_generateProxy(JNIEnv* env, jclass, jstring javaName, jobjectArray javaInterfaces, jobject javaLoader, jobjectArray javaMethods, jobjectArray javaThrows) {
+static jclass Proxy_generateProxy(JNIEnv* env, jclass, jstring javaName,
+ jobjectArray javaInterfaces, jobject javaLoader,
+ jobjectArray javaMethods, jobjectArray javaThrows) {
ScopedObjectAccess soa(env);
- String* name = soa.Decode<String*>(javaName);
- ObjectArray<Class>* interfaces = soa.Decode<ObjectArray<Class>*>(javaInterfaces);
- ClassLoader* loader = soa.Decode<ClassLoader*>(javaLoader);
- ObjectArray<AbstractMethod>* methods = soa.Decode<ObjectArray<AbstractMethod>*>(javaMethods);
- ObjectArray<ObjectArray<Class> >* throws = soa.Decode<ObjectArray<ObjectArray<Class> >*>(javaThrows);
+ mirror::String* name = soa.Decode<mirror::String*>(javaName);
+ mirror::ObjectArray<mirror::Class>* interfaces =
+ soa.Decode<mirror::ObjectArray<mirror::Class>*>(javaInterfaces);
+ mirror::ClassLoader* loader = soa.Decode<mirror::ClassLoader*>(javaLoader);
+ mirror::ObjectArray<mirror::AbstractMethod>* methods =
+ soa.Decode<mirror::ObjectArray<mirror::AbstractMethod>*>(javaMethods);
+ mirror::ObjectArray<mirror::ObjectArray<mirror::Class> >* throws =
+ soa.Decode<mirror::ObjectArray<mirror::ObjectArray<mirror::Class> >*>(javaThrows);
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Class* result = class_linker->CreateProxyClass(name, interfaces, loader, methods, throws);
+ mirror::Class* result = class_linker->CreateProxyClass(name, interfaces, loader, methods, throws);
return soa.AddLocalReference<jclass>(result);
}
diff --git a/src/native/sun_misc_Unsafe.cc b/src/native/sun_misc_Unsafe.cc
index cb06a0b..abb0d5c 100644
--- a/src/native/sun_misc_Unsafe.cc
+++ b/src/native/sun_misc_Unsafe.cc
@@ -14,15 +14,18 @@
* limitations under the License.
*/
+#include "atomic.h"
+#include "gc/card_table-inl.h"
#include "jni_internal.h"
-#include "object.h"
+#include "mirror/object.h"
+#include "mirror/object-inl.h"
#include "scoped_thread_state_change.h"
namespace art {
static jboolean Unsafe_compareAndSwapInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, jint expectedValue, jint newValue) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
byte* raw_addr = reinterpret_cast<byte*>(obj) + offset;
volatile int32_t* address = reinterpret_cast<volatile int32_t*>(raw_addr);
// Note: android_atomic_release_cas() returns 0 on success, not failure.
@@ -32,7 +35,7 @@
static jboolean Unsafe_compareAndSwapLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, jlong expectedValue, jlong newValue) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
byte* raw_addr = reinterpret_cast<byte*>(obj) + offset;
volatile int64_t* address = reinterpret_cast<volatile int64_t*>(raw_addr);
// Note: android_atomic_cmpxchg() returns 0 on success, not failure.
@@ -42,9 +45,9 @@
static jboolean Unsafe_compareAndSwapObject(JNIEnv* env, jobject, jobject javaObj, jlong offset, jobject javaExpectedValue, jobject javaNewValue) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
- Object* expectedValue = soa.Decode<Object*>(javaExpectedValue);
- Object* newValue = soa.Decode<Object*>(javaNewValue);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
+ mirror::Object* expectedValue = soa.Decode<mirror::Object*>(javaExpectedValue);
+ mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
byte* raw_addr = reinterpret_cast<byte*>(obj) + offset;
int32_t* address = reinterpret_cast<int32_t*>(raw_addr);
// Note: android_atomic_cmpxchg() returns 0 on success, not failure.
@@ -58,98 +61,98 @@
static jint Unsafe_getInt(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
return obj->GetField32(MemberOffset(offset), false);
}
static jint Unsafe_getIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
return obj->GetField32(MemberOffset(offset), true);
}
static void Unsafe_putInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, jint newValue) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
obj->SetField32(MemberOffset(offset), newValue, false);
}
static void Unsafe_putIntVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset, jint newValue) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
obj->SetField32(MemberOffset(offset), newValue, true);
}
static void Unsafe_putOrderedInt(JNIEnv* env, jobject, jobject javaObj, jlong offset, jint newValue) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
ANDROID_MEMBAR_STORE();
obj->SetField32(MemberOffset(offset), newValue, false);
}
static jlong Unsafe_getLong(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
return obj->GetField64(MemberOffset(offset), false);
}
static jlong Unsafe_getLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
return obj->GetField64(MemberOffset(offset), true);
}
static void Unsafe_putLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, jlong newValue) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
obj->SetField64(MemberOffset(offset), newValue, false);
}
static void Unsafe_putLongVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset, jlong newValue) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
obj->SetField64(MemberOffset(offset), newValue, true);
}
static void Unsafe_putOrderedLong(JNIEnv* env, jobject, jobject javaObj, jlong offset, jlong newValue) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
ANDROID_MEMBAR_STORE();
obj->SetField64(MemberOffset(offset), newValue, false);
}
static jobject Unsafe_getObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
- Object* value = obj->GetFieldObject<Object*>(MemberOffset(offset), true);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
+ mirror::Object* value = obj->GetFieldObject<mirror::Object*>(MemberOffset(offset), true);
return soa.AddLocalReference<jobject>(value);
}
static jobject Unsafe_getObject(JNIEnv* env, jobject, jobject javaObj, jlong offset) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
- Object* value = obj->GetFieldObject<Object*>(MemberOffset(offset), false);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
+ mirror::Object* value = obj->GetFieldObject<mirror::Object*>(MemberOffset(offset), false);
return soa.AddLocalReference<jobject>(value);
}
static void Unsafe_putObject(JNIEnv* env, jobject, jobject javaObj, jlong offset, jobject javaNewValue) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
- Object* newValue = soa.Decode<Object*>(javaNewValue);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
+ mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
obj->SetFieldObject(MemberOffset(offset), newValue, false);
}
static void Unsafe_putObjectVolatile(JNIEnv* env, jobject, jobject javaObj, jlong offset, jobject javaNewValue) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
- Object* newValue = soa.Decode<Object*>(javaNewValue);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
+ mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
obj->SetFieldObject(MemberOffset(offset), newValue, true);
}
static void Unsafe_putOrderedObject(JNIEnv* env, jobject, jobject javaObj, jlong offset, jobject javaNewValue) {
ScopedObjectAccess soa(env);
- Object* obj = soa.Decode<Object*>(javaObj);
- Object* newValue = soa.Decode<Object*>(javaNewValue);
+ mirror::Object* obj = soa.Decode<mirror::Object*>(javaObj);
+ mirror::Object* newValue = soa.Decode<mirror::Object*>(javaNewValue);
ANDROID_MEMBAR_STORE();
obj->SetFieldObject(MemberOffset(offset), newValue, false);
}
diff --git a/src/nth_caller_visitor.h b/src/nth_caller_visitor.h
index efed163..7d9feb6 100644
--- a/src/nth_caller_visitor.h
+++ b/src/nth_caller_visitor.h
@@ -17,10 +17,11 @@
#ifndef ART_SRC_NTH_CALLER_VISITOR_H_
#define ART_SRC_NTH_CALLER_VISITOR_H_
-#include "object.h"
-#include "thread.h"
+#include "mirror/abstract_method.h"
+#include "stack.h"
namespace art {
+class Thread;
// Walks up the stack 'n' callers, when used with Thread::WalkStack.
struct NthCallerVisitor : public StackVisitor {
@@ -38,7 +39,7 @@
size_t n;
size_t count;
- AbstractMethod* caller;
+ mirror::AbstractMethod* caller;
};
} // namespace art
diff --git a/src/oat.cc b/src/oat.cc
index 8032a11..b0a9aef 100644
--- a/src/oat.cc
+++ b/src/oat.cc
@@ -15,6 +15,7 @@
*/
#include "oat.h"
+#include "utils.h"
#include <zlib.h>
diff --git a/src/oat/jni/arm/jni_internal_arm.cc b/src/oat/jni/arm/jni_internal_arm.cc
index 36d436f..4af4f52 100644
--- a/src/oat/jni/arm/jni_internal_arm.cc
+++ b/src/oat/jni/arm/jni_internal_arm.cc
@@ -23,9 +23,9 @@
#include "compiler.h"
#include "invoke_arg_array_builder.h"
#include "jni_internal.h"
+#include "mirror/abstract_method.h"
#include "oat/utils/arm/assembler_arm.h"
#include "oat/utils/assembler.h"
-#include "object.h"
namespace art {
namespace arm {
@@ -131,7 +131,7 @@
}
// Load the code pointer we are about to call.
- __ LoadFromOffset(kLoadWord, IP, R0, AbstractMethod::GetCodeOffset().Int32Value());
+ __ LoadFromOffset(kLoadWord, IP, R0, mirror::AbstractMethod::GetCodeOffset().Int32Value());
// Do the call.
__ blx(IP);
diff --git a/src/oat/jni/jni_compiler.cc b/src/oat/jni/jni_compiler.cc
index ac35143..c0298de 100644
--- a/src/oat/jni/jni_compiler.cc
+++ b/src/oat/jni/jni_compiler.cc
@@ -118,7 +118,7 @@
// Check sirt offset is within frame
CHECK_LT(sirt_offset.Uint32Value(), frame_size);
__ LoadRef(main_jni_conv->InterproceduralScratchRegister(),
- mr_conv->MethodRegister(), AbstractMethod::DeclaringClassOffset());
+ mr_conv->MethodRegister(), mirror::AbstractMethod::DeclaringClassOffset());
__ VerifyObject(main_jni_conv->InterproceduralScratchRegister(), false);
__ StoreRef(sirt_offset, main_jni_conv->InterproceduralScratchRegister());
main_jni_conv->Next(); // in SIRT so move to next argument
@@ -269,7 +269,7 @@
}
// 9. Plant call to native code associated with method.
- __ Call(main_jni_conv->MethodStackOffset(), AbstractMethod::NativeMethodOffset(),
+ __ Call(main_jni_conv->MethodStackOffset(), mirror::AbstractMethod::NativeMethodOffset(),
mr_conv->InterproceduralScratchRegister());
// 10. Fix differences in result widths.
diff --git a/src/oat/jni/mips/jni_internal_mips.cc b/src/oat/jni/mips/jni_internal_mips.cc
index 4cfeaa9..69e86c3 100644
--- a/src/oat/jni/mips/jni_internal_mips.cc
+++ b/src/oat/jni/mips/jni_internal_mips.cc
@@ -23,9 +23,9 @@
#include "compiler.h"
#include "invoke_arg_array_builder.h"
#include "jni_internal.h"
+#include "mirror/abstract_method.h"
#include "oat/utils/mips/assembler_mips.h"
#include "oat/utils/assembler.h"
-#include "object.h"
namespace art {
namespace mips {
@@ -128,7 +128,7 @@
}
// Load the code pointer we are about to call.
- __ LoadFromOffset(kLoadWord, T9, A0, AbstractMethod::GetCodeOffset().Int32Value());
+ __ LoadFromOffset(kLoadWord, T9, A0, mirror::AbstractMethod::GetCodeOffset().Int32Value());
// Do the call.
__ Jalr(T9);
diff --git a/src/oat/jni/x86/jni_internal_x86.cc b/src/oat/jni/x86/jni_internal_x86.cc
index 9d41eda..fabd283 100644
--- a/src/oat/jni/x86/jni_internal_x86.cc
+++ b/src/oat/jni/x86/jni_internal_x86.cc
@@ -18,9 +18,9 @@
#include "compiler.h"
#include "invoke_arg_array_builder.h"
#include "jni_internal.h"
+#include "mirror/abstract_method.h"
#include "oat/utils/assembler.h"
#include "oat/utils/x86/assembler_x86.h"
-#include "object.h"
namespace art {
namespace x86 {
@@ -127,7 +127,7 @@
}
}
- __ call(Address(EAX, AbstractMethod::GetCodeOffset())); // Call code off of method
+ __ call(Address(EAX, mirror::AbstractMethod::GetCodeOffset())); // Call code off of method
// Pop arguments up to EBX and the return address.
__ addl(ESP, Immediate(frame_size + pad_size - (2 * kPointerSize)));
diff --git a/src/oat/runtime/argument_visitor.h b/src/oat/runtime/argument_visitor.h
index 06256ca..df7bc12 100644
--- a/src/oat/runtime/argument_visitor.h
+++ b/src/oat/runtime/argument_visitor.h
@@ -46,7 +46,7 @@
#define STACK_ARG_SKIP 0
#endif
- ArgumentVisitor(MethodHelper& caller_mh, AbstractMethod** sp)
+ ArgumentVisitor(MethodHelper& caller_mh, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) :
caller_mh_(caller_mh),
args_in_regs_(ComputeArgsInRegs(caller_mh)),
diff --git a/src/oat/runtime/arm/context_arm.cc b/src/oat/runtime/arm/context_arm.cc
index 5bd4b3d..2e76050 100644
--- a/src/oat/runtime/arm/context_arm.cc
+++ b/src/oat/runtime/arm/context_arm.cc
@@ -16,7 +16,9 @@
#include "context_arm.h"
-#include "object.h"
+#include "mirror/abstract_method.h"
+#include "stack.h"
+#include "thread.h"
namespace art {
namespace arm {
@@ -38,7 +40,7 @@
}
void ArmContext::FillCalleeSaves(const StackVisitor& fr) {
- AbstractMethod* method = fr.GetMethod();
+ mirror::AbstractMethod* method = fr.GetMethod();
uint32_t core_spills = method->GetCoreSpillMask();
uint32_t fp_core_spills = method->GetFpSpillMask();
size_t spill_count = __builtin_popcount(core_spills);
diff --git a/src/oat/runtime/arm/oat_support_entrypoints_arm.cc b/src/oat/runtime/arm/oat_support_entrypoints_arm.cc
index 15218b8..c43b7e2 100644
--- a/src/oat/runtime/arm/oat_support_entrypoints_arm.cc
+++ b/src/oat/runtime/arm/oat_support_entrypoints_arm.cc
@@ -28,12 +28,13 @@
extern "C" void* art_check_and_alloc_array_from_code_with_access_check(uint32_t, void*, int32_t);
// Cast entrypoints.
-extern "C" uint32_t artIsAssignableFromCode(const Class* klass, const Class* ref_class);
+extern "C" uint32_t artIsAssignableFromCode(const mirror::Class* klass,
+ const mirror::Class* ref_class);
extern "C" void art_can_put_array_element_from_code(void*, void*);
extern "C" void art_check_cast_from_code(void*, void*);
// Debug entrypoints.
-extern void DebugMe(AbstractMethod* method, uint32_t info);
+extern void DebugMe(mirror::AbstractMethod* method, uint32_t info);
extern "C" void art_update_debugger(void*, void*, int32_t, void*);
// DexCache entrypoints.
@@ -69,11 +70,11 @@
extern void JniMethodEnd(uint32_t saved_local_ref_cookie, Thread* self);
extern void JniMethodEndSynchronized(uint32_t saved_local_ref_cookie, jobject locked,
Thread* self);
-extern Object* JniMethodEndWithReference(jobject result, uint32_t saved_local_ref_cookie,
- Thread* self);
-extern Object* JniMethodEndWithReferenceSynchronized(jobject result,
- uint32_t saved_local_ref_cookie,
- jobject locked, Thread* self);
+extern mirror::Object* JniMethodEndWithReference(jobject result, uint32_t saved_local_ref_cookie,
+ Thread* self);
+extern mirror::Object* JniMethodEndWithReferenceSynchronized(jobject result,
+ uint32_t saved_local_ref_cookie,
+ jobject locked, Thread* self);
// Lock entrypoints.
extern "C" void art_lock_object_from_code(void*);
@@ -113,7 +114,8 @@
extern "C" int32_t art_string_compareto(void*, void*);
// Invoke entrypoints.
-const void* UnresolvedDirectMethodTrampolineFromCode(AbstractMethod*, AbstractMethod**, Thread*,
+const void* UnresolvedDirectMethodTrampolineFromCode(mirror::AbstractMethod*,
+ mirror::AbstractMethod**, Thread*,
Runtime::TrampolineType);
extern "C" void art_invoke_direct_trampoline_with_access_check(uint32_t, void*);
extern "C" void art_invoke_interface_trampoline(uint32_t, void*);
@@ -127,7 +129,8 @@
extern "C" void art_test_suspend();
// Throw entrypoints.
-extern void ThrowAbstractMethodErrorFromCode(AbstractMethod* method, Thread* thread, AbstractMethod** sp);
+extern void ThrowAbstractMethodErrorFromCode(mirror::AbstractMethod* method, Thread* thread,
+ mirror::AbstractMethod** sp);
extern "C" void art_deliver_exception_from_code(void*);
extern "C" void art_throw_array_bounds_from_code(int32_t index, int32_t limit);
extern "C" void art_throw_div_zero_from_code();
diff --git a/src/oat/runtime/arm/stub_arm.cc b/src/oat/runtime/arm/stub_arm.cc
index 4099ddb..90dfffc 100644
--- a/src/oat/runtime/arm/stub_arm.cc
+++ b/src/oat/runtime/arm/stub_arm.cc
@@ -15,10 +15,10 @@
*/
#include "jni_internal.h"
+#include "mirror/array.h"
#include "oat/utils/arm/assembler_arm.h"
#include "oat/runtime/oat_support_entrypoints.h"
#include "oat/runtime/stub.h"
-#include "object.h"
#include "stack_indirect_reference_table.h"
#include "sirt_ref.h"
@@ -27,7 +27,7 @@
namespace art {
namespace arm {
-ByteArray* ArmCreateResolutionTrampoline(Runtime::TrampolineType type) {
+mirror::ByteArray* ArmCreateResolutionTrampoline(Runtime::TrampolineType type) {
UniquePtr<ArmAssembler> assembler(static_cast<ArmAssembler*>(Assembler::Create(kArm)));
#if !defined(ART_USE_LLVM_COMPILER)
// | Out args |
@@ -83,7 +83,7 @@
assembler->EmitSlowPaths();
size_t cs = assembler->CodeSize();
Thread* self = Thread::Current();
- SirtRef<ByteArray> resolution_trampoline(self, ByteArray::Alloc(self, cs));
+ SirtRef<mirror::ByteArray> resolution_trampoline(self, mirror::ByteArray::Alloc(self, cs));
CHECK(resolution_trampoline.get() != NULL);
MemoryRegion code(resolution_trampoline->GetData(), resolution_trampoline->GetLength());
assembler->FinalizeInstructions(code);
@@ -91,9 +91,9 @@
return resolution_trampoline.get();
}
-typedef void (*ThrowAme)(AbstractMethod*, Thread*);
+typedef void (*ThrowAme)(mirror::AbstractMethod*, Thread*);
-ByteArray* CreateAbstractMethodErrorStub() {
+mirror::ByteArray* CreateAbstractMethodErrorStub() {
UniquePtr<ArmAssembler> assembler(static_cast<ArmAssembler*>(Assembler::Create(kArm)));
#if !defined(ART_USE_LLVM_COMPILER)
// Save callee saves and ready frame for exception delivery
@@ -130,7 +130,7 @@
size_t cs = assembler->CodeSize();
Thread* self = Thread::Current();
- SirtRef<ByteArray> abstract_stub(self, ByteArray::Alloc(self, cs));
+ SirtRef<mirror::ByteArray> abstract_stub(self, mirror::ByteArray::Alloc(self, cs));
CHECK(abstract_stub.get() != NULL);
MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength());
assembler->FinalizeInstructions(code);
@@ -138,7 +138,7 @@
return abstract_stub.get();
}
-ByteArray* CreateJniDlsymLookupStub() {
+mirror::ByteArray* CreateJniDlsymLookupStub() {
UniquePtr<ArmAssembler> assembler(static_cast<ArmAssembler*>(Assembler::Create(kArm)));
// Build frame and save argument registers and LR.
RegList save = (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3) | (1 << LR);
@@ -159,7 +159,7 @@
size_t cs = assembler->CodeSize();
Thread* self = Thread::Current();
- SirtRef<ByteArray> jni_stub(self, ByteArray::Alloc(self, cs));
+ SirtRef<mirror::ByteArray> jni_stub(self, mirror::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/callee_save_frame.h b/src/oat/runtime/callee_save_frame.h
index fe66b91..08cf9d8 100644
--- a/src/oat/runtime/callee_save_frame.h
+++ b/src/oat/runtime/callee_save_frame.h
@@ -21,11 +21,12 @@
#include "thread.h"
namespace art {
-
+namespace mirror {
class AbstractMethod;
+} // namespace mirror
// Place a special frame at the TOS that will save the callee saves for the given type.
-static void FinishCalleeSaveFrameSetup(Thread* self, AbstractMethod** sp,
+static void FinishCalleeSaveFrameSetup(Thread* self, mirror::AbstractMethod** sp,
Runtime::CalleeSaveType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Be aware the store below may well stomp on an incoming argument.
diff --git a/src/oat/runtime/mips/context_mips.cc b/src/oat/runtime/mips/context_mips.cc
index 0c2f915..36eb5b9 100644
--- a/src/oat/runtime/mips/context_mips.cc
+++ b/src/oat/runtime/mips/context_mips.cc
@@ -16,7 +16,7 @@
#include "context_mips.h"
-#include "object.h"
+#include "mirror/object.h"
namespace art {
namespace mips {
diff --git a/src/oat/runtime/mips/stub_mips.cc b/src/oat/runtime/mips/stub_mips.cc
index 4cb8813..fda9941 100644
--- a/src/oat/runtime/mips/stub_mips.cc
+++ b/src/oat/runtime/mips/stub_mips.cc
@@ -15,10 +15,10 @@
*/
#include "jni_internal.h"
+#include "mirror/array.h"
#include "oat/runtime/oat_support_entrypoints.h"
#include "oat/runtime/stub.h"
#include "oat/utils/mips/assembler_mips.h"
-#include "object.h"
#include "stack_indirect_reference_table.h"
#include "sirt_ref.h"
@@ -27,7 +27,7 @@
namespace art {
namespace mips {
-ByteArray* MipsCreateResolutionTrampoline(Runtime::TrampolineType type) {
+mirror::ByteArray* MipsCreateResolutionTrampoline(Runtime::TrampolineType type) {
UniquePtr<MipsAssembler> assembler(static_cast<MipsAssembler*>(Assembler::Create(kMips)));
#if !defined(ART_USE_LLVM_COMPILER)
// | Out args |
@@ -113,7 +113,7 @@
size_t cs = assembler->CodeSize();
Thread* self = Thread::Current();
- SirtRef<ByteArray> resolution_trampoline(self, ByteArray::Alloc(self, cs));
+ SirtRef<mirror::ByteArray> resolution_trampoline(self, mirror::ByteArray::Alloc(self, cs));
CHECK(resolution_trampoline.get() != NULL);
MemoryRegion code(resolution_trampoline->GetData(), resolution_trampoline->GetLength());
assembler->FinalizeInstructions(code);
@@ -121,9 +121,9 @@
return resolution_trampoline.get();
}
-typedef void (*ThrowAme)(AbstractMethod*, Thread*);
+typedef void (*ThrowAme)(mirror::AbstractMethod*, Thread*);
-ByteArray* CreateAbstractMethodErrorStub() {
+mirror::ByteArray* CreateAbstractMethodErrorStub() {
UniquePtr<MipsAssembler> assembler(static_cast<MipsAssembler*>(Assembler::Create(kMips)));
#if !defined(ART_USE_LLVM_COMPILER)
// Save callee saves and ready frame for exception delivery
@@ -161,7 +161,7 @@
size_t cs = assembler->CodeSize();
Thread* self = Thread::Current();
- SirtRef<ByteArray> abstract_stub(self, ByteArray::Alloc(self, cs));
+ SirtRef<mirror::ByteArray> abstract_stub(self, mirror::ByteArray::Alloc(self, cs));
CHECK(abstract_stub.get() != NULL);
MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength());
assembler->FinalizeInstructions(code);
@@ -169,7 +169,7 @@
return abstract_stub.get();
}
-ByteArray* CreateJniDlsymLookupStub() {
+mirror::ByteArray* CreateJniDlsymLookupStub() {
UniquePtr<MipsAssembler> assembler(static_cast<MipsAssembler*>(Assembler::Create(kMips)));
// Build frame and save argument registers and RA.
@@ -203,7 +203,7 @@
size_t cs = assembler->CodeSize();
Thread* self = Thread::Current();
- SirtRef<ByteArray> jni_stub(self, ByteArray::Alloc(self, cs));
+ SirtRef<mirror::ByteArray> jni_stub(self, mirror::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/oat_support_entrypoints.h b/src/oat/runtime/oat_support_entrypoints.h
index 113a56c..a08a584 100644
--- a/src/oat/runtime/oat_support_entrypoints.h
+++ b/src/oat/runtime/oat_support_entrypoints.h
@@ -24,10 +24,12 @@
static_cast<uintptr_t>(OFFSETOF_MEMBER(EntryPoints, x)))
namespace art {
-
-class Class;
-class DvmDex;
+namespace mirror {
class AbstractMethod;
+class Class;
+class Object;
+} // namespace mirror
+class DvmDex;
class Thread;
struct PACKED(4) EntryPoints {
@@ -40,12 +42,12 @@
void* (*pCheckAndAllocArrayFromCodeWithAccessCheck)(uint32_t, void*, int32_t);
// Cast
- uint32_t (*pInstanceofNonTrivialFromCode)(const Class*, const Class*);
+ uint32_t (*pInstanceofNonTrivialFromCode)(const mirror::Class*, const mirror::Class*);
void (*pCanPutArrayElementFromCode)(void*, void*);
void (*pCheckCastFromCode)(void*, void*);
// Debug
- void (*pDebugMe)(AbstractMethod*, uint32_t);
+ void (*pDebugMe)(mirror::AbstractMethod*, uint32_t);
void (*pUpdateDebuggerFromCode)(void*, void*, int32_t, void*);
// DexCache
@@ -77,8 +79,8 @@
uint32_t (*pJniMethodStartSynchronized)(jobject to_lock, Thread* self);
void (*pJniMethodEnd)(uint32_t cookie, Thread* self);
void (*pJniMethodEndSynchronized)(uint32_t cookie, jobject locked, Thread* self);
- Object* (*pJniMethodEndWithReference)(jobject result, uint32_t cookie, Thread* self);
- Object* (*pJniMethodEndWithReferenceSynchronized)(jobject result, uint32_t cookie,
+ mirror::Object* (*pJniMethodEndWithReference)(jobject result, uint32_t cookie, Thread* self);
+ mirror::Object* (*pJniMethodEndWithReferenceSynchronized)(jobject result, uint32_t cookie,
jobject locked, Thread* self);
// Locks
@@ -114,7 +116,8 @@
void* (*pMemcpy)(void*, const void*, size_t);
// Invocation
- const void* (*pUnresolvedDirectMethodTrampolineFromCode)(AbstractMethod*, AbstractMethod**, Thread*,
+ const void* (*pUnresolvedDirectMethodTrampolineFromCode)(mirror::AbstractMethod*,
+ mirror::AbstractMethod**, Thread*,
Runtime::TrampolineType);
void (*pInvokeDirectTrampolineWithAccessCheck)(uint32_t, void*);
void (*pInvokeInterfaceTrampoline)(uint32_t, void*);
@@ -129,7 +132,8 @@
// Throws
void (*pDeliverException)(void*);
- void (*pThrowAbstractMethodErrorFromCode)(AbstractMethod* m, Thread* thread, AbstractMethod** sp);
+ void (*pThrowAbstractMethodErrorFromCode)(mirror::AbstractMethod* m, Thread* thread,
+ mirror::AbstractMethod** sp);
void (*pThrowArrayBoundsFromCode)(int32_t, int32_t);
void (*pThrowDivZeroFromCode)();
void (*pThrowNoSuchMethodFromCode)(int32_t);
diff --git a/src/oat/runtime/stub.h b/src/oat/runtime/stub.h
index 0e5f0dd..2679793 100644
--- a/src/oat/runtime/stub.h
+++ b/src/oat/runtime/stub.h
@@ -20,31 +20,35 @@
#include "runtime.h"
namespace art {
+namespace mirror {
+template<class T> class PrimitiveArray;
+typedef PrimitiveArray<int8_t> ByteArray;
+} // namespace mirror
namespace arm {
- ByteArray* CreateAbstractMethodErrorStub()
+ mirror::ByteArray* CreateAbstractMethodErrorStub()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ByteArray* ArmCreateResolutionTrampoline(Runtime::TrampolineType type)
+ mirror::ByteArray* ArmCreateResolutionTrampoline(Runtime::TrampolineType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ByteArray* CreateJniDlsymLookupStub()
+ mirror::ByteArray* CreateJniDlsymLookupStub()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
}
namespace mips {
- ByteArray* CreateAbstractMethodErrorStub()
+ mirror::ByteArray* CreateAbstractMethodErrorStub()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ByteArray* MipsCreateResolutionTrampoline(Runtime::TrampolineType type)
+ mirror::ByteArray* MipsCreateResolutionTrampoline(Runtime::TrampolineType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ByteArray* CreateJniDlsymLookupStub()
+ mirror::ByteArray* CreateJniDlsymLookupStub()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
}
namespace x86 {
- ByteArray* CreateAbstractMethodErrorStub()
+ mirror::ByteArray* CreateAbstractMethodErrorStub()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ByteArray* X86CreateResolutionTrampoline(Runtime::TrampolineType type)
+ mirror::ByteArray* X86CreateResolutionTrampoline(Runtime::TrampolineType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ByteArray* CreateJniDlsymLookupStub()
+ mirror::ByteArray* CreateJniDlsymLookupStub()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
}
diff --git a/src/oat/runtime/support_alloc.cc b/src/oat/runtime/support_alloc.cc
index fb70285..5e3af78 100644
--- a/src/oat/runtime/support_alloc.cc
+++ b/src/oat/runtime/support_alloc.cc
@@ -15,51 +15,61 @@
*/
#include "callee_save_frame.h"
+#include "mirror/class-inl.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object_array-inl.h"
#include "runtime_support.h"
namespace art {
-extern "C" Object* artAllocObjectFromCode(uint32_t type_idx, AbstractMethod* method,
- Thread* self, AbstractMethod** sp)
+extern "C" mirror::Object* artAllocObjectFromCode(uint32_t type_idx, mirror::AbstractMethod* method,
+ Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
return AllocObjectFromCode(type_idx, method, self, false);
}
-extern "C" Object* artAllocObjectFromCodeWithAccessCheck(uint32_t type_idx, AbstractMethod* method,
- Thread* self, AbstractMethod** sp)
+extern "C" mirror::Object* artAllocObjectFromCodeWithAccessCheck(uint32_t type_idx,
+ mirror::AbstractMethod* method,
+ Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
return AllocObjectFromCode(type_idx, method, self, true);
}
-extern "C" Array* artAllocArrayFromCode(uint32_t type_idx, AbstractMethod* method, int32_t component_count,
- Thread* self, AbstractMethod** sp)
+extern "C" mirror::Array* artAllocArrayFromCode(uint32_t type_idx, mirror::AbstractMethod* method,
+ int32_t component_count, Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
return AllocArrayFromCode(type_idx, method, component_count, self, false);
}
-extern "C" Array* artAllocArrayFromCodeWithAccessCheck(uint32_t type_idx, AbstractMethod* method,
- int32_t component_count,
- Thread* self, AbstractMethod** sp)
+extern "C" mirror::Array* artAllocArrayFromCodeWithAccessCheck(uint32_t type_idx,
+ mirror::AbstractMethod* method,
+ int32_t component_count,
+ Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
return AllocArrayFromCode(type_idx, method, component_count, self, true);
}
-extern "C" Array* artCheckAndAllocArrayFromCode(uint32_t type_idx, AbstractMethod* method,
- int32_t component_count, Thread* self,
- AbstractMethod** sp)
+extern "C" mirror::Array* artCheckAndAllocArrayFromCode(uint32_t type_idx,
+ mirror::AbstractMethod* method,
+ int32_t component_count, Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
return CheckAndAllocArrayFromCode(type_idx, method, component_count, self, false);
}
-extern "C" Array* artCheckAndAllocArrayFromCodeWithAccessCheck(uint32_t type_idx,
- AbstractMethod* method,
- int32_t component_count,
- Thread* self, AbstractMethod** sp)
+extern "C" mirror::Array* artCheckAndAllocArrayFromCodeWithAccessCheck(uint32_t type_idx,
+ mirror::AbstractMethod* method,
+ int32_t component_count,
+ Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
return CheckAndAllocArrayFromCode(type_idx, method, component_count, self, true);
diff --git a/src/oat/runtime/support_cast.cc b/src/oat/runtime/support_cast.cc
index 0db743b..71a37ef 100644
--- a/src/oat/runtime/support_cast.cc
+++ b/src/oat/runtime/support_cast.cc
@@ -15,12 +15,15 @@
*/
#include "callee_save_frame.h"
+#include "mirror/class-inl.h"
+#include "mirror/object-inl.h"
#include "runtime_support.h"
namespace art {
// Assignable test for code, won't throw. Null and equality tests already performed
-extern "C" uint32_t artIsAssignableFromCode(const Class* klass, const Class* ref_class)
+extern "C" uint32_t artIsAssignableFromCode(const mirror::Class* klass,
+ const mirror::Class* ref_class)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(klass != NULL);
DCHECK(ref_class != NULL);
@@ -28,8 +31,8 @@
}
// Check whether it is safe to cast one class to the other, throw exception and return -1 on failure
-extern "C" int artCheckCastFromCode(const Class* a, const Class* b, Thread* self,
- AbstractMethod** sp)
+extern "C" int artCheckCastFromCode(const mirror::Class* a, const mirror::Class* b, Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(a->IsClass()) << PrettyClass(a);
DCHECK(b->IsClass()) << PrettyClass(b);
@@ -47,13 +50,14 @@
// Tests whether 'element' can be assigned into an array of type 'array_class'.
// Returns 0 on success and -1 if an exception is pending.
-extern "C" int artCanPutArrayElementFromCode(const Object* element, const Class* array_class,
- Thread* self, AbstractMethod** sp)
+extern "C" int artCanPutArrayElementFromCode(const mirror::Object* element,
+ const mirror::Class* array_class,
+ Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(array_class != NULL);
// element can't be NULL as we catch this is screened in runtime_support
- Class* element_class = element->GetClass();
- Class* component_type = array_class->GetComponentType();
+ mirror::Class* element_class = element->GetClass();
+ mirror::Class* component_type = array_class->GetComponentType();
if (LIKELY(component_type->IsAssignableFrom(element_class))) {
return 0; // Success
} else {
diff --git a/src/oat/runtime/support_debug.cc b/src/oat/runtime/support_debug.cc
index e2ca493..0d67dd9 100644
--- a/src/oat/runtime/support_debug.cc
+++ b/src/oat/runtime/support_debug.cc
@@ -25,14 +25,14 @@
* method entry and offset 0 within the method, we'll use an offset of -1
* to denote method entry.
*/
-extern "C" void artUpdateDebuggerFromCode(int32_t dex_pc, Thread* self, AbstractMethod** sp)
+extern "C" void artUpdateDebuggerFromCode(int32_t dex_pc, Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsAndArgs);
Dbg::UpdateDebugger(dex_pc, self);
}
// Temporary debugging hook for compiler.
-extern void DebugMe(AbstractMethod* method, uint32_t info)
+extern void DebugMe(mirror::AbstractMethod* method, uint32_t info)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
LOG(INFO) << "DebugMe";
if (method != NULL) {
diff --git a/src/oat/runtime/support_deoptimize.cc b/src/oat/runtime/support_deoptimize.cc
index 75e671f..0d88c52 100644
--- a/src/oat/runtime/support_deoptimize.cc
+++ b/src/oat/runtime/support_deoptimize.cc
@@ -16,7 +16,8 @@
#include "callee_save_frame.h"
#include "interpreter/interpreter.h"
-#include "object.h" // for JValue
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object_array-inl.h"
#include "object_utils.h"
#include "stack.h"
#include "thread.h"
@@ -24,7 +25,7 @@
namespace art {
-extern "C" uint64_t artDeoptimize(JValue ret_val, Thread* self, AbstractMethod** sp)
+extern "C" uint64_t artDeoptimize(JValue ret_val, Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
// Return value may hold Object* so avoid suspension.
@@ -36,7 +37,7 @@
: StackVisitor(thread, context), shadow_frame_(NULL), runtime_frames_(0) { }
virtual bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* m = GetMethod();
+ mirror::AbstractMethod* m = GetMethod();
if (m->IsRuntimeMethod()) {
if (runtime_frames_ == 0) {
runtime_frames_++;
@@ -84,7 +85,7 @@
}
-extern "C" JValue artEnterInterpreterFromDeoptimize(Thread* self, AbstractMethod** sp)
+extern "C" JValue artEnterInterpreterFromDeoptimize(Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
JValue return_value;
diff --git a/src/oat/runtime/support_dexcache.cc b/src/oat/runtime/support_dexcache.cc
index 10c7930..da15917 100644
--- a/src/oat/runtime/support_dexcache.cc
+++ b/src/oat/runtime/support_dexcache.cc
@@ -15,12 +15,17 @@
*/
#include "callee_save_frame.h"
+#include "class_linker-inl.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object_array-inl.h"
#include "runtime_support.h"
namespace art {
-extern "C" Class* artInitializeStaticStorageFromCode(uint32_t type_idx, const AbstractMethod* referrer,
- Thread* self, AbstractMethod** sp)
+extern "C" mirror::Class* artInitializeStaticStorageFromCode(uint32_t type_idx,
+ const mirror::AbstractMethod* referrer,
+ Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Called to ensure static storage base is initialized for direct static field reads and writes.
// A class may be accessing another class' fields when it doesn't have access, as access has been
@@ -29,18 +34,19 @@
return ResolveVerifyAndClinit(type_idx, referrer, self, true, false);
}
-extern "C" Class* artInitializeTypeFromCode(uint32_t type_idx, const AbstractMethod* referrer,
- Thread* self, AbstractMethod** sp)
+extern "C" mirror::Class* artInitializeTypeFromCode(uint32_t type_idx,
+ const mirror::AbstractMethod* referrer,
+ Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Called when method->dex_cache_resolved_types_[] misses.
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
return ResolveVerifyAndClinit(type_idx, referrer, self, false, false);
}
-extern "C" Class* artInitializeTypeAndVerifyAccessFromCode(uint32_t type_idx,
- const AbstractMethod* referrer,
- Thread* self,
- AbstractMethod** sp)
+extern "C" mirror::Class* artInitializeTypeAndVerifyAccessFromCode(uint32_t type_idx,
+ const mirror::AbstractMethod* referrer,
+ Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Called when caller isn't guaranteed to have access to a type and the dex cache may be
// unpopulated.
@@ -48,8 +54,9 @@
return ResolveVerifyAndClinit(type_idx, referrer, self, false, true);
}
-extern "C" String* artResolveStringFromCode(AbstractMethod* referrer, int32_t string_idx,
- Thread* self, AbstractMethod** sp)
+extern "C" mirror::String* artResolveStringFromCode(mirror::AbstractMethod* referrer,
+ int32_t string_idx,
+ Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
return ResolveStringFromCode(referrer, string_idx);
diff --git a/src/oat/runtime/support_field.cc b/src/oat/runtime/support_field.cc
index 9336247..a564fa9 100644
--- a/src/oat/runtime/support_field.cc
+++ b/src/oat/runtime/support_field.cc
@@ -15,16 +15,20 @@
*/
#include "callee_save_frame.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/class-inl.h"
+#include "mirror/field-inl.h"
#include "runtime_support.h"
#include <stdint.h>
namespace art {
-extern "C" uint32_t artGet32StaticFromCode(uint32_t field_idx, const AbstractMethod* referrer,
- Thread* self, AbstractMethod** sp)
+extern "C" uint32_t artGet32StaticFromCode(uint32_t field_idx,
+ const mirror::AbstractMethod* referrer,
+ Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int32_t));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int32_t));
if (LIKELY(field != NULL)) {
return field->Get32(field->GetDeclaringClass());
}
@@ -36,10 +40,11 @@
return 0; // Will throw exception by checking with Thread::Current
}
-extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx, const AbstractMethod* referrer,
- Thread* self, AbstractMethod** sp)
+extern "C" uint64_t artGet64StaticFromCode(uint32_t field_idx,
+ const mirror::AbstractMethod* referrer,
+ Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int64_t));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(int64_t));
if (LIKELY(field != NULL)) {
return field->Get64(field->GetDeclaringClass());
}
@@ -51,26 +56,28 @@
return 0; // Will throw exception by checking with Thread::Current
}
-extern "C" Object* artGetObjStaticFromCode(uint32_t field_idx, const AbstractMethod* referrer,
- Thread* self, AbstractMethod** sp)
+extern "C" mirror::Object* artGetObjStaticFromCode(uint32_t field_idx,
+ const mirror::AbstractMethod* referrer,
+ Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, StaticObjectRead, sizeof(Object*));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, StaticObjectRead,
+ sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
return field->GetObj(field->GetDeclaringClass());
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- field = FindFieldFromCode(field_idx, referrer, self, StaticObjectRead, sizeof(Object*));
+ field = FindFieldFromCode(field_idx, referrer, self, StaticObjectRead, sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
return field->GetObj(field->GetDeclaringClass());
}
return NULL; // Will throw exception by checking with Thread::Current
}
-extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx, Object* obj,
- const AbstractMethod* referrer, Thread* self,
- AbstractMethod** sp)
+extern "C" uint32_t artGet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
+ const mirror::AbstractMethod* referrer, Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int32_t));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int32_t));
if (LIKELY(field != NULL && obj != NULL)) {
return field->Get32(obj);
}
@@ -86,11 +93,11 @@
return 0; // Will throw exception by checking with Thread::Current
}
-extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, Object* obj,
- const AbstractMethod* referrer, Thread* self,
- AbstractMethod** sp)
+extern "C" uint64_t artGet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj,
+ const mirror::AbstractMethod* referrer, Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int64_t));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(int64_t));
if (LIKELY(field != NULL && obj != NULL)) {
return field->Get64(obj);
}
@@ -106,16 +113,17 @@
return 0; // Will throw exception by checking with Thread::Current
}
-extern "C" Object* artGetObjInstanceFromCode(uint32_t field_idx, Object* obj,
- const AbstractMethod* referrer, Thread* self,
- AbstractMethod** sp)
+extern "C" mirror::Object* artGetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
+ const mirror::AbstractMethod* referrer,
+ Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, InstanceObjectRead, sizeof(Object*));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, InstanceObjectRead, sizeof(mirror::Object*));
if (LIKELY(field != NULL && obj != NULL)) {
return field->GetObj(obj);
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectRead, sizeof(Object*));
+ field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectRead, sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
if (UNLIKELY(obj == NULL)) {
ThrowNullPointerExceptionForFieldAccess(field, true);
@@ -127,10 +135,10 @@
}
extern "C" int artSet32StaticFromCode(uint32_t field_idx, uint32_t new_value,
- const AbstractMethod* referrer, Thread* self,
- AbstractMethod** sp)
+ const mirror::AbstractMethod* referrer, Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int32_t));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int32_t));
if (LIKELY(field != NULL)) {
field->Set32(field->GetDeclaringClass(), new_value);
return 0; // success
@@ -144,10 +152,10 @@
return -1; // failure
}
-extern "C" int artSet64StaticFromCode(uint32_t field_idx, const AbstractMethod* referrer,
- uint64_t new_value, Thread* self, AbstractMethod** sp)
+extern "C" int artSet64StaticFromCode(uint32_t field_idx, const mirror::AbstractMethod* referrer,
+ uint64_t new_value, Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int64_t));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(int64_t));
if (LIKELY(field != NULL)) {
field->Set64(field->GetDeclaringClass(), new_value);
return 0; // success
@@ -161,11 +169,12 @@
return -1; // failure
}
-extern "C" int artSetObjStaticFromCode(uint32_t field_idx, Object* new_value,
- const AbstractMethod* referrer, Thread* self,
- AbstractMethod** sp)
+extern "C" int artSetObjStaticFromCode(uint32_t field_idx, mirror::Object* new_value,
+ const mirror::AbstractMethod* referrer, Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, StaticObjectWrite, sizeof(Object*));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, StaticObjectWrite,
+ sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
if (LIKELY(!FieldHelper(field).IsPrimitiveType())) {
field->SetObj(field->GetDeclaringClass(), new_value);
@@ -173,7 +182,7 @@
}
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- field = FindFieldFromCode(field_idx, referrer, self, StaticObjectWrite, sizeof(Object*));
+ field = FindFieldFromCode(field_idx, referrer, self, StaticObjectWrite, sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
field->SetObj(field->GetDeclaringClass(), new_value);
return 0; // success
@@ -181,11 +190,11 @@
return -1; // failure
}
-extern "C" int artSet32InstanceFromCode(uint32_t field_idx, Object* obj, uint32_t new_value,
- const AbstractMethod* referrer, Thread* self,
- AbstractMethod** sp)
+extern "C" int artSet32InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint32_t new_value,
+ const mirror::AbstractMethod* referrer, Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int32_t));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int32_t));
if (LIKELY(field != NULL && obj != NULL)) {
field->Set32(obj, new_value);
return 0; // success
@@ -203,12 +212,14 @@
return -1; // failure
}
-extern "C" int artSet64InstanceFromCode(uint32_t field_idx, Object* obj, uint64_t new_value,
- Thread* self, AbstractMethod** sp)
+extern "C" int artSet64InstanceFromCode(uint32_t field_idx, mirror::Object* obj, uint64_t new_value,
+ Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* callee_save = Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsOnly);
- AbstractMethod* referrer = sp[callee_save->GetFrameSizeInBytes() / sizeof(AbstractMethod*)];
- Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(int64_t));
+ mirror::AbstractMethod* callee_save = Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsOnly);
+ mirror::AbstractMethod* referrer =
+ sp[callee_save->GetFrameSizeInBytes() / sizeof(mirror::AbstractMethod*)];
+ mirror::Field* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite,
+ sizeof(int64_t));
if (LIKELY(field != NULL && obj != NULL)) {
field->Set64(obj, new_value);
return 0; // success
@@ -227,17 +238,20 @@
return -1; // failure
}
-extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, Object* obj, Object* new_value,
- const AbstractMethod* referrer, Thread* self,
- AbstractMethod** sp)
+extern "C" int artSetObjInstanceFromCode(uint32_t field_idx, mirror::Object* obj,
+ mirror::Object* new_value,
+ const mirror::AbstractMethod* referrer, Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite, sizeof(Object*));
+ mirror::Field* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite,
+ sizeof(mirror::Object*));
if (LIKELY(field != NULL && obj != NULL)) {
field->SetObj(obj, new_value);
return 0; // success
}
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
- field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectWrite, sizeof(Object*));
+ field = FindFieldFromCode(field_idx, referrer, self, InstanceObjectWrite,
+ sizeof(mirror::Object*));
if (LIKELY(field != NULL)) {
if (UNLIKELY(obj == NULL)) {
ThrowNullPointerExceptionForFieldAccess(field, false);
diff --git a/src/oat/runtime/support_fillarray.cc b/src/oat/runtime/support_fillarray.cc
index 9c6231f..73f832a 100644
--- a/src/oat/runtime/support_fillarray.cc
+++ b/src/oat/runtime/support_fillarray.cc
@@ -16,7 +16,8 @@
#include "callee_save_frame.h"
#include "dex_instruction.h"
-#include "object.h"
+#include "mirror/array.h"
+#include "mirror/object-inl.h"
namespace art {
@@ -35,9 +36,9 @@
* ubyte data[size*width] table of data values (may contain a single-byte
* padding at the end)
*/
-extern "C" int artHandleFillArrayDataFromCode(Array* array,
+extern "C" int artHandleFillArrayDataFromCode(mirror::Array* array,
const Instruction::ArrayDataPayload* payload,
- Thread* self, AbstractMethod** sp)
+ Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
DCHECK_EQ(payload->ident, static_cast<uint16_t>(Instruction::kArrayDataSignature));
diff --git a/src/oat/runtime/support_instrumentation.cc b/src/oat/runtime/support_instrumentation.cc
index 73e4371..f65717a 100644
--- a/src/oat/runtime/support_instrumentation.cc
+++ b/src/oat/runtime/support_instrumentation.cc
@@ -22,8 +22,10 @@
namespace art {
-extern "C" const void* artInstrumentationMethodEntryFromCode(AbstractMethod* method, Thread* self,
- AbstractMethod** sp, uintptr_t lr)
+extern "C" const void* artInstrumentationMethodEntryFromCode(mirror::AbstractMethod* method,
+ Thread* self,
+ mirror::AbstractMethod** sp,
+ uintptr_t lr)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
self->SetTopOfStack(sp, lr);
self->VerifyStack();
@@ -41,7 +43,7 @@
return instrumentation->GetSavedCodeFromMap(method);
}
-extern "C" uint64_t artInstrumentationMethodExitFromCode(Thread* self, AbstractMethod** sp)
+extern "C" uint64_t artInstrumentationMethodExitFromCode(Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
self->SetTopOfStack(sp, 0);
self->VerifyStack();
diff --git a/src/oat/runtime/support_interpreter.cc b/src/oat/runtime/support_interpreter.cc
index 98751cc..a02ef27 100644
--- a/src/oat/runtime/support_interpreter.cc
+++ b/src/oat/runtime/support_interpreter.cc
@@ -17,7 +17,9 @@
#include "argument_visitor.h"
#include "callee_save_frame.h"
#include "interpreter/interpreter.h"
-#include "object.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object.h"
+#include "mirror/object_array-inl.h"
#include "object_utils.h"
namespace art {
@@ -25,7 +27,7 @@
// Visits arguments on the stack placing them into the shadow frame.
class BuildShadowFrameVisitor : public ArgumentVisitor {
public:
- BuildShadowFrameVisitor(MethodHelper& caller_mh, AbstractMethod** sp,
+ BuildShadowFrameVisitor(MethodHelper& caller_mh, mirror::AbstractMethod** sp,
ShadowFrame& sf, size_t first_arg_reg) :
ArgumentVisitor(caller_mh, sp), sf_(sf), cur_reg_(first_arg_reg) {}
@@ -41,7 +43,7 @@
}
break;
case Primitive::kPrimNot:
- sf_.SetVRegReference(cur_reg_, *reinterpret_cast<Object**>(GetParamAddress()));
+ sf_.SetVRegReference(cur_reg_, *reinterpret_cast<mirror::Object**>(GetParamAddress()));
break;
case Primitive::kPrimBoolean: // Fall-through.
case Primitive::kPrimByte: // Fall-through.
@@ -65,7 +67,8 @@
DISALLOW_COPY_AND_ASSIGN(BuildShadowFrameVisitor);
};
-extern "C" uint64_t artInterpreterEntry(AbstractMethod* method, Thread* self, AbstractMethod** sp)
+extern "C" uint64_t artInterpreterEntry(mirror::AbstractMethod* method, Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Ensure we don't get thread suspension until the object arguments are safely in the shadow
// frame.
diff --git a/src/oat/runtime/support_invoke.cc b/src/oat/runtime/support_invoke.cc
index 7a49489..438ac8f 100644
--- a/src/oat/runtime/support_invoke.cc
+++ b/src/oat/runtime/support_invoke.cc
@@ -15,16 +15,22 @@
*/
#include "callee_save_frame.h"
+#include "dex_instruction.h"
+#include "mirror/class-inl.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
#include "runtime_support.h"
namespace art {
// Determine target of interface dispatch. This object is known non-null.
-extern "C" uint64_t artInvokeInterfaceTrampoline(AbstractMethod* interface_method,
- Object* this_object, AbstractMethod* caller_method,
- Thread* self, AbstractMethod** sp)
+extern "C" uint64_t artInvokeInterfaceTrampoline(mirror::AbstractMethod* interface_method,
+ mirror::Object* this_object,
+ mirror::AbstractMethod* caller_method,
+ Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method;
+ mirror::AbstractMethod* method;
if (LIKELY(interface_method->GetDexMethodIndex() != DexFile::kDexNoIndex16)) {
method = this_object->GetClass()->FindVirtualMethodForInterface(interface_method);
if (UNLIKELY(method == NULL)) {
@@ -131,10 +137,13 @@
}
-static uint64_t artInvokeCommon(uint32_t method_idx, Object* this_object, AbstractMethod* caller_method,
- Thread* self, AbstractMethod** sp, bool access_check, InvokeType type)
+static uint64_t artInvokeCommon(uint32_t method_idx, mirror::Object* this_object,
+ mirror::AbstractMethod* caller_method,
+ Thread* self, mirror::AbstractMethod** sp, bool access_check,
+ InvokeType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method = FindMethodFast(method_idx, this_object, caller_method, access_check, type);
+ mirror::AbstractMethod* method = FindMethodFast(method_idx, this_object, caller_method,
+ access_check, type);
if (UNLIKELY(method == NULL)) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsAndArgs);
method = FindMethodFromCode(method_idx, this_object, caller_method, self, access_check, type);
@@ -163,47 +172,47 @@
// See comments in runtime_support_asm.S
extern "C" uint64_t artInvokeInterfaceTrampolineWithAccessCheck(uint32_t method_idx,
- Object* this_object,
- AbstractMethod* caller_method,
+ mirror::Object* this_object,
+ mirror::AbstractMethod* caller_method,
Thread* self,
- AbstractMethod** sp)
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return artInvokeCommon(method_idx, this_object, caller_method, self, sp, true, kInterface);
}
extern "C" uint64_t artInvokeDirectTrampolineWithAccessCheck(uint32_t method_idx,
- Object* this_object,
- AbstractMethod* caller_method,
+ mirror::Object* this_object,
+ mirror::AbstractMethod* caller_method,
Thread* self,
- AbstractMethod** sp)
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return artInvokeCommon(method_idx, this_object, caller_method, self, sp, true, kDirect);
}
extern "C" uint64_t artInvokeStaticTrampolineWithAccessCheck(uint32_t method_idx,
- Object* this_object,
- AbstractMethod* caller_method,
- Thread* self,
- AbstractMethod** sp)
+ mirror::Object* this_object,
+ mirror::AbstractMethod* caller_method,
+ Thread* self,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return artInvokeCommon(method_idx, this_object, caller_method, self, sp, true, kStatic);
}
extern "C" uint64_t artInvokeSuperTrampolineWithAccessCheck(uint32_t method_idx,
- Object* this_object,
- AbstractMethod* caller_method,
+ mirror::Object* this_object,
+ mirror::AbstractMethod* caller_method,
Thread* self,
- AbstractMethod** sp)
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return artInvokeCommon(method_idx, this_object, caller_method, self, sp, true, kSuper);
}
extern "C" uint64_t artInvokeVirtualTrampolineWithAccessCheck(uint32_t method_idx,
- Object* this_object,
- AbstractMethod* caller_method,
+ mirror::Object* this_object,
+ mirror::AbstractMethod* caller_method,
Thread* self,
- AbstractMethod** sp)
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return artInvokeCommon(method_idx, this_object, caller_method, self, sp, true, kVirtual);
}
diff --git a/src/oat/runtime/support_jni.cc b/src/oat/runtime/support_jni.cc
index e1ae530..0e21700 100644
--- a/src/oat/runtime/support_jni.cc
+++ b/src/oat/runtime/support_jni.cc
@@ -14,7 +14,11 @@
* limitations under the License.
*/
-#include "object.h"
+#include "mirror/class-inl.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
#include "object_utils.h"
#include "runtime_support.h"
#include "scoped_thread_state_change.h"
@@ -28,7 +32,7 @@
DCHECK(Thread::Current() == self);
ScopedObjectAccess soa(self);
- AbstractMethod* method = self->GetCurrentMethod();
+ mirror::AbstractMethod* method = self->GetCurrentMethod();
DCHECK(method != NULL);
// Lookup symbol address for method, on failure we'll return NULL with an
@@ -81,11 +85,11 @@
PopLocalReferences(saved_local_ref_cookie, self);
}
-extern Object* JniMethodEndWithReference(jobject result, uint32_t saved_local_ref_cookie,
- Thread* self)
+extern mirror::Object* JniMethodEndWithReference(jobject result, uint32_t saved_local_ref_cookie,
+ Thread* self)
SHARED_LOCK_FUNCTION(Locks::mutator_lock_) {
self->TransitionFromSuspendedToRunnable();
- Object* o = self->DecodeJObject(result); // Must decode before pop.
+ mirror::Object* o = self->DecodeJObject(result); // Must decode before pop.
PopLocalReferences(saved_local_ref_cookie, self);
// Process result.
if (UNLIKELY(self->GetJniEnv()->check_jni)) {
@@ -97,13 +101,13 @@
return o;
}
-extern Object* JniMethodEndWithReferenceSynchronized(jobject result,
- uint32_t saved_local_ref_cookie,
- jobject locked, Thread* self)
+extern mirror::Object* JniMethodEndWithReferenceSynchronized(jobject result,
+ uint32_t saved_local_ref_cookie,
+ jobject locked, Thread* self)
SHARED_LOCK_FUNCTION(Locks::mutator_lock_) {
self->TransitionFromSuspendedToRunnable();
UnlockJniSynchronizedMethod(locked, self); // Must decode before pop.
- Object* o = self->DecodeJObject(result);
+ mirror::Object* o = self->DecodeJObject(result);
PopLocalReferences(saved_local_ref_cookie, self);
// Process result.
if (UNLIKELY(self->GetJniEnv()->check_jni)) {
@@ -117,9 +121,10 @@
static void WorkAroundJniBugsForJobject(intptr_t* arg_ptr) {
intptr_t value = *arg_ptr;
- Object** value_as_jni_rep = reinterpret_cast<Object**>(value);
- Object* value_as_work_around_rep = value_as_jni_rep != NULL ? *value_as_jni_rep : NULL;
- CHECK(Runtime::Current()->GetHeap()->IsHeapAddress(value_as_work_around_rep)) << value_as_work_around_rep;
+ mirror::Object** value_as_jni_rep = reinterpret_cast<mirror::Object**>(value);
+ mirror::Object* value_as_work_around_rep = value_as_jni_rep != NULL ? *value_as_jni_rep : NULL;
+ CHECK(Runtime::Current()->GetHeap()->IsHeapAddress(value_as_work_around_rep))
+ << value_as_work_around_rep;
*arg_ptr = reinterpret_cast<intptr_t>(value_as_work_around_rep);
}
@@ -137,7 +142,7 @@
// | unused |
// | unused |
// | unused | <- sp
- AbstractMethod* jni_method = self->GetCurrentMethod();
+ mirror::AbstractMethod* jni_method = self->GetCurrentMethod();
DCHECK(jni_method->IsNative()) << PrettyMethod(jni_method);
intptr_t* arg_ptr = sp + 4; // pointer to r1 on stack
// Fix up this/jclass argument
diff --git a/src/oat/runtime/support_locks.cc b/src/oat/runtime/support_locks.cc
index f3a3106..38fc48c 100644
--- a/src/oat/runtime/support_locks.cc
+++ b/src/oat/runtime/support_locks.cc
@@ -15,11 +15,12 @@
*/
#include "callee_save_frame.h"
-#include "object.h"
+#include "mirror/object.h"
namespace art {
-extern "C" int artUnlockObjectFromCode(Object* obj, Thread* self, AbstractMethod** sp)
+extern "C" int artUnlockObjectFromCode(mirror::Object* obj, Thread* self,
+ mirror::AbstractMethod** sp)
UNLOCK_FUNCTION(monitor_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsOnly);
DCHECK(obj != NULL); // Assumed to have been checked before entry
@@ -27,7 +28,8 @@
return obj->MonitorExit(self) ? 0 /* Success */ : -1 /* Failure */;
}
-extern "C" void artLockObjectFromCode(Object* obj, Thread* thread, AbstractMethod** sp)
+extern "C" void artLockObjectFromCode(mirror::Object* obj, Thread* thread,
+ mirror::AbstractMethod** sp)
EXCLUSIVE_LOCK_FUNCTION(monitor_lock_) {
FinishCalleeSaveFrameSetup(thread, sp, Runtime::kRefsOnly);
DCHECK(obj != NULL); // Assumed to have been checked before entry
diff --git a/src/oat/runtime/support_proxy.cc b/src/oat/runtime/support_proxy.cc
index f0f07a1..65e404a 100644
--- a/src/oat/runtime/support_proxy.cc
+++ b/src/oat/runtime/support_proxy.cc
@@ -15,7 +15,9 @@
*/
#include "argument_visitor.h"
-#include "object.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object.h"
+#include "mirror/object_array-inl.h"
#include "object_utils.h"
#include "reflection.h"
#include "runtime_support.h"
@@ -31,7 +33,7 @@
// to jobjects.
class BuildArgumentVisitor : public ArgumentVisitor {
public:
- BuildArgumentVisitor(MethodHelper& caller_mh, AbstractMethod** sp,
+ BuildArgumentVisitor(MethodHelper& caller_mh, mirror::AbstractMethod** sp,
ScopedObjectAccessUnchecked& soa, std::vector<jvalue>& args) :
ArgumentVisitor(caller_mh, sp), soa_(soa), args_(args) {}
@@ -40,7 +42,7 @@
Primitive::Type type = GetParamPrimitiveType();
switch (type) {
case Primitive::kPrimNot: {
- Object* obj = *reinterpret_cast<Object**>(GetParamAddress());
+ mirror::Object* obj = *reinterpret_cast<mirror::Object**>(GetParamAddress());
val.l = soa_.AddLocalReference<jobject>(obj);
break;
}
@@ -79,8 +81,9 @@
// which is responsible for recording callee save registers. We explicitly place into jobjects the
// incoming reference arguments (so they survive GC). We invoke the invocation handler, which is a
// field within the proxy object, which will box the primitive arguments and deal with error cases.
-extern "C" uint64_t artProxyInvokeHandler(AbstractMethod* proxy_method, Object* receiver,
- Thread* self, AbstractMethod** sp)
+extern "C" uint64_t artProxyInvokeHandler(mirror::AbstractMethod* proxy_method,
+ mirror::Object* receiver,
+ Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Ensure we don't get thread suspension until the object arguments are safely in jobjects.
const char* old_cause =
@@ -106,7 +109,7 @@
args.erase(args.begin());
// Convert proxy method into expected interface method.
- AbstractMethod* interface_method = proxy_method->FindOverriddenMethod();
+ mirror::AbstractMethod* interface_method = proxy_method->FindOverriddenMethod();
DCHECK(interface_method != NULL);
DCHECK(!interface_method->IsProxyMethod()) << PrettyMethod(interface_method);
jobject interface_method_jobj = soa.AddLocalReference<jobject>(interface_method);
diff --git a/src/oat/runtime/support_stubs.cc b/src/oat/runtime/support_stubs.cc
index ac188a8..dcfea3a 100644
--- a/src/oat/runtime/support_stubs.cc
+++ b/src/oat/runtime/support_stubs.cc
@@ -17,8 +17,12 @@
#if !defined(ART_USE_LLVM_COMPILER)
#include "callee_save_frame.h"
#endif
+#include "class_linker-inl.h"
#include "dex_instruction.h"
-#include "object.h"
+#include "mirror/class-inl.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object.h"
+#include "mirror/object_array-inl.h"
#include "object_utils.h"
#if defined(ART_USE_LLVM_COMPILER)
#include "nth_caller_visitor.h"
@@ -32,7 +36,8 @@
#if !defined(ART_USE_LLVM_COMPILER)
// Lazily resolve a method. Called by stub code.
-const void* UnresolvedDirectMethodTrampolineFromCode(AbstractMethod* called, AbstractMethod** sp, Thread* thread,
+const void* UnresolvedDirectMethodTrampolineFromCode(mirror::AbstractMethod* called,
+ mirror::AbstractMethod** sp, Thread* thread,
Runtime::TrampolineType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
#if defined(__arm__)
@@ -52,7 +57,7 @@
// | R0 |
// | Method* | <- sp
DCHECK_EQ(48U, Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)->GetFrameSizeInBytes());
- AbstractMethod** caller_sp = reinterpret_cast<AbstractMethod**>(reinterpret_cast<byte*>(sp) + 48);
+ mirror::AbstractMethod** caller_sp = reinterpret_cast<mirror::AbstractMethod**>(reinterpret_cast<byte*>(sp) + 48);
uintptr_t* regs = reinterpret_cast<uintptr_t*>(reinterpret_cast<byte*>(sp) + kPointerSize);
uint32_t pc_offset = 10;
uintptr_t caller_pc = regs[pc_offset];
@@ -72,7 +77,7 @@
// | ECX | arg1
// | EAX/Method* | <- sp
DCHECK_EQ(32U, Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)->GetFrameSizeInBytes());
- AbstractMethod** caller_sp = reinterpret_cast<AbstractMethod**>(reinterpret_cast<byte*>(sp) + 32);
+ mirror::AbstractMethod** caller_sp = reinterpret_cast<mirror::AbstractMethod**>(reinterpret_cast<byte*>(sp) + 32);
uintptr_t* regs = reinterpret_cast<uintptr_t*>(reinterpret_cast<byte*>(sp));
uintptr_t caller_pc = regs[7];
#elif defined(__mips__)
@@ -91,13 +96,13 @@
// | A1 | arg1
// | A0/Method* | <- sp
DCHECK_EQ(48U, Runtime::Current()->GetCalleeSaveMethod(Runtime::kRefsAndArgs)->GetFrameSizeInBytes());
- AbstractMethod** caller_sp = reinterpret_cast<AbstractMethod**>(reinterpret_cast<byte*>(sp) + 48);
+ mirror::AbstractMethod** caller_sp = reinterpret_cast<mirror::AbstractMethod**>(reinterpret_cast<byte*>(sp) + 48);
uintptr_t* regs = reinterpret_cast<uintptr_t*>(reinterpret_cast<byte*>(sp));
uint32_t pc_offset = 11;
uintptr_t caller_pc = regs[pc_offset];
#else
UNIMPLEMENTED(FATAL);
- AbstractMethod** caller_sp = NULL;
+ mirror::AbstractMethod** caller_sp = NULL;
uintptr_t* regs = NULL;
uintptr_t caller_pc = 0;
#endif
@@ -109,7 +114,7 @@
// Compute details about the called method (avoid GCs)
ClassLinker* linker = Runtime::Current()->GetClassLinker();
- AbstractMethod* caller = *caller_sp;
+ mirror::AbstractMethod* caller = *caller_sp;
InvokeType invoke_type;
uint32_t dex_method_idx;
#if !defined(__i386__)
@@ -173,7 +178,7 @@
// Place into local references incoming arguments from the caller's register arguments
size_t cur_arg = 1; // skip method_idx in R0, first arg is in R1
if (invoke_type != kStatic) {
- Object* obj = reinterpret_cast<Object*>(regs[cur_arg]);
+ mirror::Object* obj = reinterpret_cast<mirror::Object*>(regs[cur_arg]);
cur_arg++;
if (args_in_regs < 3) {
// If we thought we had fewer than 3 arguments in registers, account for the receiver
@@ -188,7 +193,7 @@
char c = shorty[shorty_index];
shorty_index++;
if (c == 'L') {
- Object* obj = reinterpret_cast<Object*>(regs[cur_arg]);
+ mirror::Object* obj = reinterpret_cast<mirror::Object*>(regs[cur_arg]);
soa.AddLocalReference<jobject>(obj);
}
cur_arg = cur_arg + (c == 'J' || c == 'D' ? 2 : 1);
@@ -199,7 +204,7 @@
char c = shorty[shorty_index];
shorty_index++;
if (c == 'L') {
- Object* obj = reinterpret_cast<Object*>(regs[cur_arg]);
+ mirror::Object* obj = reinterpret_cast<mirror::Object*>(regs[cur_arg]);
soa.AddLocalReference<jobject>(obj);
}
cur_arg = cur_arg + (c == 'J' || c == 'D' ? 2 : 1);
@@ -214,7 +219,7 @@
// Incompatible class change should have been handled in resolve method.
CHECK(!called->CheckIncompatibleClassChange(invoke_type));
// Ensure that the called method's class is initialized.
- Class* called_class = called->GetDeclaringClass();
+ mirror::Class* called_class = called->GetDeclaringClass();
linker->EnsureInitialized(called_class, true, true);
if (LIKELY(called_class->IsInitialized())) {
code = called->GetCode();
@@ -252,7 +257,7 @@
Thread* thread, Runtime::TrampolineType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
uint32_t dex_pc;
- AbstractMethod* caller = thread->GetCurrentMethod(&dex_pc);
+ mirror::AbstractMethod* caller = thread->GetCurrentMethod(&dex_pc);
ClassLinker* linker = Runtime::Current()->GetClassLinker();
InvokeType invoke_type;
@@ -299,7 +304,7 @@
// Incompatible class change should have been handled in resolve method.
CHECK(!called->CheckIncompatibleClassChange(invoke_type));
// Ensure that the called method's class is initialized.
- Class* called_class = called->GetDeclaringClass();
+ mirror::Class* called_class = called->GetDeclaringClass();
linker->EnsureInitialized(called_class, true, true);
if (LIKELY(called_class->IsInitialized())) {
code = called->GetCode();
@@ -342,7 +347,8 @@
#if !defined(ART_USE_LLVM_COMPILER)
// Called by the AbstractMethodError. Called by stub code.
-extern void ThrowAbstractMethodErrorFromCode(AbstractMethod* method, Thread* thread, AbstractMethod** sp)
+extern void ThrowAbstractMethodErrorFromCode(mirror::AbstractMethod* method, Thread* thread,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
thread->ThrowNewExceptionF("Ljava/lang/AbstractMethodError;",
@@ -350,7 +356,8 @@
thread->QuickDeliverException();
}
#else // ART_USE_LLVM_COMPILER
-extern void ThrowAbstractMethodErrorFromCode(AbstractMethod* method, Thread* thread, AbstractMethod**)
+extern void ThrowAbstractMethodErrorFromCode(mirror::AbstractMethod* method, Thread* thread,
+ mirror::AbstractMethod**)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
thread->ThrowNewExceptionF("Ljava/lang/AbstractMethodError;",
"abstract method \"%s\"", PrettyMethod(method).c_str());
diff --git a/src/oat/runtime/support_thread.cc b/src/oat/runtime/support_thread.cc
index 04038ab..e711714 100644
--- a/src/oat/runtime/support_thread.cc
+++ b/src/oat/runtime/support_thread.cc
@@ -28,7 +28,7 @@
CheckSuspend(thread);
}
-extern "C" void artTestSuspendFromCode(Thread* thread, AbstractMethod** sp)
+extern "C" void artTestSuspendFromCode(Thread* thread, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Called when suspend count check value is 0 and thread->suspend_count_ != 0
FinishCalleeSaveFrameSetup(thread, sp, Runtime::kRefsOnly);
diff --git a/src/oat/runtime/support_throw.cc b/src/oat/runtime/support_throw.cc
index 5bf48e4..80ba118 100644
--- a/src/oat/runtime/support_throw.cc
+++ b/src/oat/runtime/support_throw.cc
@@ -15,7 +15,7 @@
*/
#include "callee_save_frame.h"
-#include "object.h"
+#include "mirror/object.h"
#include "object_utils.h"
#include "runtime_support.h"
#include "thread.h"
@@ -26,21 +26,21 @@
// Used to implement MOVE_EXCEPTION.
extern "C" void* GetAndClearException(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(self->IsExceptionPending());
- Throwable* exception = self->GetException();
+ mirror::Throwable* exception = self->GetException();
self->ClearException();
return exception;
}
// Deliver an exception that's pending on thread helping set up a callee save frame on the way.
-extern "C" void artDeliverPendingExceptionFromCode(Thread* thread, AbstractMethod** sp)
+extern "C" void artDeliverPendingExceptionFromCode(Thread* thread, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
thread->QuickDeliverException();
}
// Called by generated call to throw an exception.
-extern "C" void artDeliverExceptionFromCode(Throwable* exception, Thread* thread,
- AbstractMethod** sp)
+extern "C" void artDeliverExceptionFromCode(mirror::Throwable* exception, Thread* thread,
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
/*
* exception may be NULL, in which case this routine should
@@ -56,18 +56,18 @@
// Called by generated call to throw a NPE exception.
extern "C" void artThrowNullPointerExceptionFromCode(Thread* self,
- AbstractMethod** sp)
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
uint32_t dex_pc;
- AbstractMethod* throw_method = self->GetCurrentMethod(&dex_pc);
+ mirror::AbstractMethod* throw_method = self->GetCurrentMethod(&dex_pc);
ThrowNullPointerExceptionFromDexPC(throw_method, dex_pc);
self->QuickDeliverException();
}
// Called by generated call to throw an arithmetic divide by zero exception.
extern "C" void artThrowDivZeroFromCode(Thread* thread,
- AbstractMethod** sp)
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
thread->ThrowNewException("Ljava/lang/ArithmeticException;", "divide by zero");
@@ -76,7 +76,7 @@
// Called by generated call to throw an array index out of bounds exception.
extern "C" void artThrowArrayBoundsFromCode(int index, int limit, Thread* thread,
- AbstractMethod** sp)
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(thread, sp, Runtime::kSaveAll);
thread->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
@@ -84,7 +84,7 @@
thread->QuickDeliverException();
}
-extern "C" void artThrowStackOverflowFromCode(Thread* self, AbstractMethod** sp)
+extern "C" void artThrowStackOverflowFromCode(Thread* self, mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
ThrowStackOverflowError(self);
@@ -92,10 +92,10 @@
}
extern "C" void artThrowNoSuchMethodFromCode(int32_t method_idx, Thread* self,
- AbstractMethod** sp)
+ mirror::AbstractMethod** sp)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FinishCalleeSaveFrameSetup(self, sp, Runtime::kSaveAll);
- AbstractMethod* method = self->GetCurrentMethod();
+ mirror::AbstractMethod* method = self->GetCurrentMethod();
ThrowNoSuchMethodError(method_idx, method);
self->QuickDeliverException();
}
diff --git a/src/oat/runtime/x86/context_x86.cc b/src/oat/runtime/x86/context_x86.cc
index 4efdf81..9d930ca 100644
--- a/src/oat/runtime/x86/context_x86.cc
+++ b/src/oat/runtime/x86/context_x86.cc
@@ -16,7 +16,8 @@
#include "context_x86.h"
-#include "object.h"
+#include "mirror/abstract_method.h"
+#include "stack.h"
namespace art {
namespace x86 {
@@ -34,7 +35,7 @@
}
void X86Context::FillCalleeSaves(const StackVisitor& fr) {
- AbstractMethod* method = fr.GetMethod();
+ mirror::AbstractMethod* method = fr.GetMethod();
uint32_t core_spills = method->GetCoreSpillMask();
size_t spill_count = __builtin_popcount(core_spills);
DCHECK_EQ(method->GetFpSpillMask(), 0u);
diff --git a/src/oat/runtime/x86/oat_support_entrypoints_x86.cc b/src/oat/runtime/x86/oat_support_entrypoints_x86.cc
index fce2251..445ae2a 100644
--- a/src/oat/runtime/x86/oat_support_entrypoints_x86.cc
+++ b/src/oat/runtime/x86/oat_support_entrypoints_x86.cc
@@ -28,12 +28,13 @@
extern "C" void* art_check_and_alloc_array_from_code_with_access_check(uint32_t, void*, int32_t);
// Cast entrypoints.
-extern "C" uint32_t art_is_assignable_from_code(const Class* klass, const Class* ref_class);
+extern "C" uint32_t art_is_assignable_from_code(const mirror::Class* klass,
+ const mirror::Class* ref_class);
extern "C" void art_can_put_array_element_from_code(void*, void*);
extern "C" void art_check_cast_from_code(void*, void*);
// Debug entrypoints.
-extern void DebugMe(AbstractMethod* method, uint32_t info);
+extern void DebugMe(mirror::AbstractMethod* method, uint32_t info);
extern "C" void art_update_debugger(void*, void*, int32_t, void*);
// DexCache entrypoints.
@@ -66,11 +67,11 @@
extern void JniMethodEnd(uint32_t saved_local_ref_cookie, Thread* self);
extern void JniMethodEndSynchronized(uint32_t saved_local_ref_cookie, jobject locked,
Thread* self);
-extern Object* JniMethodEndWithReference(jobject result, uint32_t saved_local_ref_cookie,
- Thread* self);
-extern Object* JniMethodEndWithReferenceSynchronized(jobject result,
- uint32_t saved_local_ref_cookie,
- jobject locked, Thread* self);
+extern mirror::Object* JniMethodEndWithReference(jobject result, uint32_t saved_local_ref_cookie,
+ Thread* self);
+extern mirror::Object* JniMethodEndWithReferenceSynchronized(jobject result,
+ uint32_t saved_local_ref_cookie,
+ jobject locked, Thread* self);
// Lock entrypoints.
extern "C" void art_lock_object_from_code(void*);
@@ -98,7 +99,8 @@
extern "C" void* art_memcpy(void*, const void*, size_t);
// Invoke entrypoints.
-const void* UnresolvedDirectMethodTrampolineFromCode(AbstractMethod*, AbstractMethod**, Thread*,
+const void* UnresolvedDirectMethodTrampolineFromCode(mirror::AbstractMethod*,
+ mirror::AbstractMethod**, Thread*,
Runtime::TrampolineType);
extern "C" void art_invoke_direct_trampoline_with_access_check(uint32_t, void*);
extern "C" void art_invoke_interface_trampoline(uint32_t, void*);
@@ -112,7 +114,8 @@
extern "C" void art_test_suspend();
// Throw entrypoints.
-extern void ThrowAbstractMethodErrorFromCode(AbstractMethod* method, Thread* thread, AbstractMethod** sp);
+extern void ThrowAbstractMethodErrorFromCode(mirror::AbstractMethod* method, Thread* thread,
+ mirror::AbstractMethod** sp);
extern "C" void art_deliver_exception_from_code(void*);
extern "C" void art_throw_array_bounds_from_code(int32_t index, int32_t limit);
extern "C" void art_throw_div_zero_from_code();
diff --git a/src/oat/runtime/x86/stub_x86.cc b/src/oat/runtime/x86/stub_x86.cc
index cade99d..92f3c5f 100644
--- a/src/oat/runtime/x86/stub_x86.cc
+++ b/src/oat/runtime/x86/stub_x86.cc
@@ -15,10 +15,10 @@
*/
#include "jni_internal.h"
+#include "mirror/array.h"
#include "oat/runtime/oat_support_entrypoints.h"
#include "oat/runtime/stub.h"
#include "oat/utils/x86/assembler_x86.h"
-#include "object.h"
#include "stack_indirect_reference_table.h"
#include "sirt_ref.h"
@@ -27,7 +27,7 @@
namespace art {
namespace x86 {
-ByteArray* X86CreateResolutionTrampoline(Runtime::TrampolineType type) {
+mirror::ByteArray* X86CreateResolutionTrampoline(Runtime::TrampolineType type) {
UniquePtr<X86Assembler> assembler(static_cast<X86Assembler*>(Assembler::Create(kX86)));
#if !defined(ART_USE_LLVM_COMPILER)
@@ -93,7 +93,7 @@
assembler->EmitSlowPaths();
size_t cs = assembler->CodeSize();
Thread* self = Thread::Current();
- SirtRef<ByteArray> resolution_trampoline(self, ByteArray::Alloc(self, cs));
+ SirtRef<mirror::ByteArray> resolution_trampoline(self, mirror::ByteArray::Alloc(self, cs));
CHECK(resolution_trampoline.get() != NULL);
MemoryRegion code(resolution_trampoline->GetData(), resolution_trampoline->GetLength());
assembler->FinalizeInstructions(code);
@@ -101,9 +101,9 @@
return resolution_trampoline.get();
}
-typedef void (*ThrowAme)(AbstractMethod*, Thread*);
+typedef void (*ThrowAme)(mirror::AbstractMethod*, Thread*);
-ByteArray* CreateAbstractMethodErrorStub() {
+mirror::ByteArray* CreateAbstractMethodErrorStub() {
UniquePtr<X86Assembler> assembler(static_cast<X86Assembler*>(Assembler::Create(kX86)));
#if !defined(ART_USE_LLVM_COMPILER)
@@ -148,7 +148,7 @@
size_t cs = assembler->CodeSize();
Thread* self = Thread::Current();
- SirtRef<ByteArray> abstract_stub(self, ByteArray::Alloc(self, cs));
+ SirtRef<mirror::ByteArray> abstract_stub(self, mirror::ByteArray::Alloc(self, cs));
CHECK(abstract_stub.get() != NULL);
MemoryRegion code(abstract_stub->GetData(), abstract_stub->GetLength());
assembler->FinalizeInstructions(code);
@@ -156,7 +156,7 @@
return abstract_stub.get();
}
-ByteArray* CreateJniDlsymLookupStub() {
+mirror::ByteArray* CreateJniDlsymLookupStub() {
UniquePtr<X86Assembler> assembler(static_cast<X86Assembler*>(Assembler::Create(kX86)));
// Pad stack to ensure 16-byte alignment
@@ -182,7 +182,7 @@
size_t cs = assembler->CodeSize();
Thread* self = Thread::Current();
- SirtRef<ByteArray> jni_stub(self, ByteArray::Alloc(self, cs));
+ SirtRef<mirror::ByteArray> jni_stub(self, mirror::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_compilation_unit.h b/src/oat_compilation_unit.h
index ec7c9a3..7eac322 100644
--- a/src/oat_compilation_unit.h
+++ b/src/oat_compilation_unit.h
@@ -22,11 +22,12 @@
#include <stdint.h>
namespace art {
-
+namespace mirror {
class ClassLoader;
+class DexCache;
+} // namespace mirror
class ClassLinker;
class DexFile;
-class DexCache;
class OatCompilationUnit {
public:
diff --git a/src/oat_file.cc b/src/oat_file.cc
index 8229f63..b806df8 100644
--- a/src/oat_file.cc
+++ b/src/oat_file.cc
@@ -22,7 +22,11 @@
#include "base/unix_file/fd_file.h"
#include "elf_file.h"
#include "oat.h"
+#include "mirror/class.h"
+#include "mirror/abstract_method.h"
+#include "mirror/abstract_method-inl.h"
#include "os.h"
+#include "utils.h"
namespace art {
@@ -296,7 +300,7 @@
const byte* oat_class_pointer = oat_file_->Begin() + oat_class_offset;
CHECK_LT(oat_class_pointer, oat_file_->End());
- Class::Status status = *reinterpret_cast<const Class::Status*>(oat_class_pointer);
+ mirror::Class::Status status = *reinterpret_cast<const mirror::Class::Status*>(oat_class_pointer);
const byte* methods_pointer = oat_class_pointer + sizeof(status);
CHECK_LT(methods_pointer, oat_file_->End());
@@ -307,13 +311,13 @@
}
OatFile::OatClass::OatClass(const OatFile* oat_file,
- Class::Status status,
+ mirror::Class::Status status,
const OatMethodOffsets* methods_pointer)
: oat_file_(oat_file), status_(status), methods_pointer_(methods_pointer) {}
OatFile::OatClass::~OatClass() {}
-Class::Status OatFile::OatClass::GetStatus() const {
+mirror::Class::Status OatFile::OatClass::GetStatus() const {
return status_;
}
@@ -392,9 +396,9 @@
return reinterpret_cast<uint32_t*>(code)[-1];
}
-AbstractMethod::InvokeStub* OatFile::OatMethod::GetInvokeStub() const {
+mirror::AbstractMethod::InvokeStub* OatFile::OatMethod::GetInvokeStub() const {
const byte* stub = GetOatPointer<const byte*>(invoke_stub_offset_);
- return reinterpret_cast<AbstractMethod::InvokeStub*>(const_cast<byte*>(stub));
+ return reinterpret_cast<mirror::AbstractMethod::InvokeStub*>(const_cast<byte*>(stub));
}
uint32_t OatFile::OatMethod::GetInvokeStubSize() const {
@@ -413,7 +417,7 @@
}
#endif
-void OatFile::OatMethod::LinkMethodPointers(AbstractMethod* method) const {
+void OatFile::OatMethod::LinkMethodPointers(mirror::AbstractMethod* method) const {
CHECK(method != NULL);
method->SetCode(GetCode());
method->SetFrameSizeInBytes(frame_size_in_bytes_);
@@ -425,7 +429,7 @@
method->SetInvokeStub(GetInvokeStub());
}
-void OatFile::OatMethod::LinkMethodOffsets(AbstractMethod* method) const {
+void OatFile::OatMethod::LinkMethodOffsets(mirror::AbstractMethod* method) const {
CHECK(method != NULL);
method->SetOatCodeOffset(GetCodeOffset());
method->SetFrameSizeInBytes(GetFrameSizeInBytes());
diff --git a/src/oat_file.h b/src/oat_file.h
index ff5cd80..bff48fa 100644
--- a/src/oat_file.h
+++ b/src/oat_file.h
@@ -20,8 +20,11 @@
#include <string>
#include <vector>
-#include "globals.h"
-#include "object.h"
+#include "dex_file.h"
+#include "invoke_type.h"
+#include "mem_map.h"
+#include "mirror/abstract_method.h"
+#include "oat.h"
#include "os.h"
namespace art {
@@ -65,10 +68,10 @@
class OatMethod {
public:
// Link Method for execution using the contents of this OatMethod
- void LinkMethodPointers(AbstractMethod* method) const;
+ void LinkMethodPointers(mirror::AbstractMethod* method) const;
// Link Method for image writing using the contents of this OatMethod
- void LinkMethodOffsets(AbstractMethod* method) const;
+ void LinkMethodOffsets(mirror::AbstractMethod* method) const;
uint32_t GetCodeOffset() const {
return code_offset_;
@@ -108,7 +111,7 @@
return GetOatPointer<const uint8_t*>(native_gc_map_offset_);
}
- AbstractMethod::InvokeStub* GetInvokeStub() const;
+ mirror::AbstractMethod::InvokeStub* GetInvokeStub() const;
uint32_t GetInvokeStubSize() const;
#if defined(ART_USE_LLVM_COMPILER)
@@ -161,7 +164,7 @@
class OatClass {
public:
- Class::Status GetStatus() const;
+ mirror::Class::Status GetStatus() const;
// get the OatMethod entry based on its index into the class
// defintion. direct methods come first, followed by virtual
@@ -172,11 +175,11 @@
private:
OatClass(const OatFile* oat_file,
- Class::Status status,
+ mirror::Class::Status status,
const OatMethodOffsets* methods_pointer);
const OatFile* oat_file_;
- const Class::Status status_;
+ const mirror::Class::Status status_;
const OatMethodOffsets* methods_pointer_;
friend class OatDexFile;
diff --git a/src/oat_test.cc b/src/oat_test.cc
index ec0fa7d..8da3626 100644
--- a/src/oat_test.cc
+++ b/src/oat_test.cc
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+#include "mirror/abstract_method-inl.h"
+#include "mirror/class-inl.h"
+#include "mirror/object_array-inl.h"
#include "oat_file.h"
#include "oat_writer.h"
#include "vector_output_stream.h"
@@ -24,7 +27,7 @@
class OatTest : public CommonTest {
protected:
- void CheckMethod(AbstractMethod* method,
+ void CheckMethod(mirror::AbstractMethod* method,
const OatFile::OatMethod& oat_method,
const DexFile* dex_file)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -119,7 +122,7 @@
UniquePtr<const OatFile::OatClass> oat_class(oat_dex_file->GetOatClass(i));
- Class* klass = class_linker->FindClass(descriptor, NULL);
+ mirror::Class* klass = class_linker->FindClass(descriptor, NULL);
size_t method_index = 0;
for (size_t i = 0; i < klass->NumDirectMethods(); i++, method_index++) {
diff --git a/src/oat_writer.cc b/src/oat_writer.cc
index 113beba..6fcea5d 100644
--- a/src/oat_writer.cc
+++ b/src/oat_writer.cc
@@ -21,7 +21,9 @@
#include "base/stl_util.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
-#include "class_loader.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/array.h"
+#include "mirror/class_loader.h"
#include "os.h"
#include "output_stream.h"
#include "safe_map.h"
@@ -134,13 +136,13 @@
Compiler::ClassReference class_ref = Compiler::ClassReference(dex_file, class_def_index);
CompiledClass* compiled_class = compiler_->GetCompiledClass(class_ref);
- Class::Status status;
+ mirror::Class::Status status;
if (compiled_class != NULL) {
status = compiled_class->GetStatus();
} else if (verifier::MethodVerifier::IsClassRejected(class_ref)) {
- status = Class::kStatusError;
+ status = mirror::Class::kStatusError;
} else {
- status = Class::kStatusNotReady;
+ status = mirror::Class::kStatusNotReady;
}
OatClass* oat_class = new OatClass(status, num_methods);
@@ -307,16 +309,18 @@
// We expect GC maps except when the class hasn't been verified or the method is native
Compiler::ClassReference class_ref = Compiler::ClassReference(dex_file, class_def_index);
CompiledClass* compiled_class = compiler_->GetCompiledClass(class_ref);
- Class::Status status;
+ mirror::Class::Status status;
if (compiled_class != NULL) {
status = compiled_class->GetStatus();
} else if (verifier::MethodVerifier::IsClassRejected(class_ref)) {
- status = Class::kStatusError;
+ status = mirror::Class::kStatusError;
} else {
- status = Class::kStatusNotReady;
+ status = mirror::Class::kStatusNotReady;
}
- CHECK(gc_map_size != 0 || is_native || status < Class::kStatusVerified)
- << &gc_map << " " << gc_map_size << " " << (is_native ? "true" : "false") << " " << (status < Class::kStatusVerified) << " " << status << " " << PrettyMethod(method_idx, *dex_file);
+ CHECK(gc_map_size != 0 || is_native || status < mirror::Class::kStatusVerified)
+ << &gc_map << " " << gc_map_size << " " << (is_native ? "true" : "false") << " "
+ << (status < mirror::Class::kStatusVerified) << " " << status << " "
+ << PrettyMethod(method_idx, *dex_file);
#endif
// Deduplicate GC maps
@@ -396,11 +400,11 @@
if (compiler_->IsImage()) {
ClassLinker* linker = Runtime::Current()->GetClassLinker();
- DexCache* dex_cache = linker->FindDexCache(*dex_file);
+ mirror::DexCache* dex_cache = linker->FindDexCache(*dex_file);
// Unchecked as we hold mutator_lock_ on entry.
ScopedObjectAccessUnchecked soa(Thread::Current());
- AbstractMethod* method = linker->ResolveMethod(*dex_file, method_idx, dex_cache,
- NULL, NULL, type);
+ mirror::AbstractMethod* method = linker->ResolveMethod(*dex_file, method_idx, dex_cache,
+ NULL, NULL, type);
CHECK(method != NULL);
method->SetFrameSizeInBytes(frame_size_in_bytes);
method->SetCoreSpillMask(core_spill_mask);
@@ -836,7 +840,7 @@
return true;
}
-OatWriter::OatClass::OatClass(Class::Status status, uint32_t methods_count) {
+OatWriter::OatClass::OatClass(mirror::Class::Status status, uint32_t methods_count) {
status_ = status;
method_offsets_.resize(methods_count);
}
diff --git a/src/oat_writer.h b/src/oat_writer.h
index 2bcbbc5..e1638d0 100644
--- a/src/oat_writer.h
+++ b/src/oat_writer.h
@@ -22,10 +22,9 @@
#include <cstddef>
#include "compiler.h"
-#include "dex_cache.h"
#include "mem_map.h"
#include "oat.h"
-#include "object.h"
+#include "mirror/class.h"
#include "safe_map.h"
#include "UniquePtr.h"
@@ -136,13 +135,13 @@
class OatClass {
public:
- explicit OatClass(Class::Status status, uint32_t methods_count);
+ explicit OatClass(mirror::Class::Status status, uint32_t methods_count);
size_t SizeOf() const;
void UpdateChecksum(OatHeader& oat_header) const;
bool Write(OutputStream& out) const;
// data to write
- Class::Status status_;
+ mirror::Class::Status status_;
std::vector<OatMethodOffsets> method_offsets_;
private:
diff --git a/src/oatdump.cc b/src/oatdump.cc
index 5ee433c..3fe62bc 100644
--- a/src/oatdump.cc
+++ b/src/oatdump.cc
@@ -25,6 +25,7 @@
#include "base/stringpiece.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
+#include "class_linker-inl.h"
#include "dex_instruction.h"
#include "disassembler.h"
#include "gc_map.h"
@@ -32,6 +33,12 @@
#include "gc/space.h"
#include "image.h"
#include "indenter.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/array-inl.h"
+#include "mirror/class-inl.h"
+#include "mirror/field-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
#include "oat.h"
#include "object_utils.h"
#include "os.h"
@@ -162,7 +169,7 @@
return oat_file_.GetOatHeader().GetInstructionSet();
}
- const void* GetOatCode(AbstractMethod* m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ const void* GetOatCode(mirror::AbstractMethod* m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
MethodHelper mh(m);
for (size_t i = 0; i < oat_dex_files_.size(); i++) {
const OatFile::OatDexFile* oat_dex_file = oat_dex_files_[i];
@@ -580,8 +587,8 @@
uint32_t method_access_flags, uint32_t dex_pc) {
bool first = true;
ScopedObjectAccess soa(Thread::Current());
- DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file);
- ClassLoader* class_loader = NULL;
+ mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file);
+ mirror::ClassLoader* class_loader = NULL;
std::vector<int32_t> kinds =
verifier::MethodVerifier::DescribeVRegs(dex_method_idx, dex_file, dex_cache,
class_loader, class_def_idx, code_item, NULL,
@@ -633,8 +640,8 @@
uint32_t method_access_flags) {
if ((method_access_flags & kAccNative) == 0) {
ScopedObjectAccess soa(Thread::Current());
- DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file);
- ClassLoader* class_loader = NULL;
+ mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file);
+ mirror::ClassLoader* class_loader = NULL;
verifier::MethodVerifier::VerifyMethodAndDump(os, dex_method_idx, dex_file, dex_cache,
class_loader, class_def_idx, code_item, NULL,
method_access_flags);
@@ -713,17 +720,17 @@
for (int i = 0; i < ImageHeader::kImageRootsMax; i++) {
ImageHeader::ImageRoot image_root = static_cast<ImageHeader::ImageRoot>(i);
const char* image_root_description = image_roots_descriptions_[i];
- Object* image_root_object = image_header_.GetImageRoot(image_root);
+ mirror::Object* image_root_object = image_header_.GetImageRoot(image_root);
indent1_os << StringPrintf("%s: %p\n", image_root_description, image_root_object);
if (image_root_object->IsObjectArray()) {
Indenter indent2_filter(indent1_os.rdbuf(), kIndentChar, kIndentBy1Count);
std::ostream indent2_os(&indent2_filter);
// TODO: replace down_cast with AsObjectArray (g++ currently has a problem with this)
- ObjectArray<Object>* image_root_object_array
- = down_cast<ObjectArray<Object>*>(image_root_object);
+ mirror::ObjectArray<mirror::Object>* image_root_object_array
+ = down_cast<mirror::ObjectArray<mirror::Object>*>(image_root_object);
// = image_root_object->AsObjectArray<Object>();
for (int i = 0; i < image_root_object_array->GetLength(); i++) {
- Object* value = image_root_object_array->Get(i);
+ mirror::Object* value = image_root_object_array->Get(i);
if (value != NULL) {
indent2_os << i << ": ";
PrettyObjectValue(indent2_os, value->GetClass(), value);
@@ -737,7 +744,7 @@
os << "\n";
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Object* oat_location_object = image_header_.GetImageRoot(ImageHeader::kOatLocation);
+ mirror::Object* oat_location_object = image_header_.GetImageRoot(ImageHeader::kOatLocation);
std::string oat_location(oat_location_object->AsString()->ToModifiedUtf8());
os << "OAT LOCATION: " << oat_location;
if (!host_prefix_.empty()) {
@@ -811,36 +818,36 @@
}
private:
- static void PrettyObjectValue(std::ostream& os, Class* type, Object* value)
+ static void PrettyObjectValue(std::ostream& os, mirror::Class* type, mirror::Object* value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK(type != NULL);
if (value == NULL) {
os << StringPrintf("null %s\n", PrettyDescriptor(type).c_str());
} else if (type->IsStringClass()) {
- String* string = value->AsString();
+ mirror::String* string = value->AsString();
os << StringPrintf("%p String: %s\n", string,
PrintableString(string->ToModifiedUtf8()).c_str());
} else if (type->IsClassClass()) {
- Class* klass = value->AsClass();
+ mirror::Class* klass = value->AsClass();
os << StringPrintf("%p Class: %s\n", klass, PrettyDescriptor(klass).c_str());
} else if (type->IsFieldClass()) {
- Field* field = value->AsField();
+ mirror::Field* field = value->AsField();
os << StringPrintf("%p Field: %s\n", field, PrettyField(field).c_str());
} else if (type->IsMethodClass()) {
- AbstractMethod* method = value->AsMethod();
+ mirror::AbstractMethod* method = value->AsMethod();
os << StringPrintf("%p Method: %s\n", method, PrettyMethod(method).c_str());
} else {
os << StringPrintf("%p %s\n", value, PrettyDescriptor(type).c_str());
}
}
- static void PrintField(std::ostream& os, Field* field, Object* obj)
+ static void PrintField(std::ostream& os, mirror::Field* field, mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
FieldHelper fh(field);
const char* descriptor = fh.GetTypeDescriptor();
os << StringPrintf("%s: ", fh.GetName());
if (descriptor[0] != 'L' && descriptor[0] != '[') {
- Class* type = fh.GetType();
+ mirror::Class* type = fh.GetType();
if (type->IsPrimitiveLong()) {
os << StringPrintf("%lld (0x%llx)\n", field->Get64(obj), field->Get64(obj));
} else if (type->IsPrimitiveDouble()) {
@@ -854,7 +861,7 @@
} else {
// Get the value, don't compute the type unless it is non-null as we don't want
// to cause class loading.
- Object* value = field->GetObj(obj);
+ mirror::Object* value = field->GetObj(obj);
if (value == NULL) {
os << StringPrintf("null %s\n", PrettyDescriptor(descriptor).c_str());
} else {
@@ -863,26 +870,26 @@
}
}
- static void DumpFields(std::ostream& os, Object* obj, Class* klass)
+ static void DumpFields(std::ostream& os, mirror::Object* obj, mirror::Class* klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Class* super = klass->GetSuperClass();
+ mirror::Class* super = klass->GetSuperClass();
if (super != NULL) {
DumpFields(os, obj, super);
}
- ObjectArray<Field>* fields = klass->GetIFields();
+ mirror::ObjectArray<mirror::Field>* fields = klass->GetIFields();
if (fields != NULL) {
for (int32_t i = 0; i < fields->GetLength(); i++) {
- Field* field = fields->Get(i);
+ mirror::Field* field = fields->Get(i);
PrintField(os, field, obj);
}
}
}
- bool InDumpSpace(const Object* object) {
+ bool InDumpSpace(const mirror::Object* object) {
return image_space_.Contains(object);
}
- const void* GetOatCodeBegin(AbstractMethod* m)
+ const void* GetOatCodeBegin(mirror::AbstractMethod* m)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Runtime* runtime = Runtime::Current();
const void* code = m->GetCode();
@@ -895,7 +902,7 @@
return code;
}
- uint32_t GetOatCodeSize(AbstractMethod* m)
+ uint32_t GetOatCodeSize(mirror::AbstractMethod* m)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const uint32_t* oat_code_begin = reinterpret_cast<const uint32_t*>(GetOatCodeBegin(m));
if (oat_code_begin == NULL) {
@@ -904,7 +911,7 @@
return oat_code_begin[-1];
}
- const void* GetOatCodeEnd(AbstractMethod* m)
+ const void* GetOatCodeEnd(mirror::AbstractMethod* m)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const uint8_t* oat_code_begin = reinterpret_cast<const uint8_t*>(GetOatCodeBegin(m));
if (oat_code_begin == NULL) {
@@ -913,7 +920,7 @@
return oat_code_begin + GetOatCodeSize(m);
}
- static void Callback(Object* obj, void* arg)
+ static void Callback(mirror::Object* obj, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(obj != NULL);
DCHECK(arg != NULL);
@@ -928,12 +935,12 @@
state->stats_.alignment_bytes += alignment_bytes;
std::ostream& os = *state->os_;
- Class* obj_class = obj->GetClass();
+ mirror::Class* obj_class = obj->GetClass();
if (obj_class->IsArrayClass()) {
os << StringPrintf("%p: %s length:%d\n", obj, PrettyDescriptor(obj_class).c_str(),
obj->AsArray()->GetLength());
} else if (obj->IsClass()) {
- Class* klass = obj->AsClass();
+ mirror::Class* klass = obj->AsClass();
os << StringPrintf("%p: java.lang.Class \"%s\" (", obj, PrettyDescriptor(klass).c_str())
<< klass->GetStatus() << ")\n";
} else if (obj->IsField()) {
@@ -952,10 +959,10 @@
std::ostream indent_os(&indent_filter);
DumpFields(indent_os, obj, obj_class);
if (obj->IsObjectArray()) {
- ObjectArray<Object>* obj_array = obj->AsObjectArray<Object>();
+ mirror::ObjectArray<mirror::Object>* obj_array = obj->AsObjectArray<mirror::Object>();
int32_t length = obj_array->GetLength();
for (int32_t i = 0; i < length; i++) {
- Object* value = obj_array->Get(i);
+ mirror::Object* value = obj_array->Get(i);
size_t run = 0;
for (int32_t j = i + 1; j < length; j++) {
if (value == obj_array->Get(j)) {
@@ -970,22 +977,22 @@
indent_os << StringPrintf("%d to %zd: ", i, i + run);
i = i + run;
}
- Class* value_class = value == NULL ? obj_class->GetComponentType() : value->GetClass();
+ mirror::Class* value_class = value == NULL ? obj_class->GetComponentType() : value->GetClass();
PrettyObjectValue(indent_os, value_class, value);
}
} else if (obj->IsClass()) {
- ObjectArray<Field>* sfields = obj->AsClass()->GetSFields();
+ mirror::ObjectArray<mirror::Field>* sfields = obj->AsClass()->GetSFields();
if (sfields != NULL) {
indent_os << "STATICS:\n";
Indenter indent2_filter(indent_os.rdbuf(), kIndentChar, kIndentBy1Count);
std::ostream indent2_os(&indent2_filter);
for (int32_t i = 0; i < sfields->GetLength(); i++) {
- Field* field = sfields->Get(i);
+ mirror::Field* field = sfields->Get(i);
PrintField(indent2_os, field, field->GetDeclaringClass());
}
}
} else if (obj->IsMethod()) {
- AbstractMethod* method = obj->AsMethod();
+ mirror::AbstractMethod* method = obj->AsMethod();
if (method->IsNative()) {
DCHECK(method->GetNativeGcMap() == NULL) << PrettyMethod(method);
DCHECK(method->GetMappingTable() == NULL) << PrettyMethod(method);
@@ -1110,7 +1117,7 @@
size_t dex_instruction_bytes;
- std::vector<AbstractMethod*> method_outlier;
+ std::vector<mirror::AbstractMethod*> method_outlier;
std::vector<size_t> method_outlier_size;
std::vector<double> method_outlier_expansion;
std::vector<std::pair<std::string, size_t> > oat_dex_file_sizes;
@@ -1163,7 +1170,7 @@
return (static_cast<double>(size) / static_cast<double>(object_bytes)) * 100;
}
- void ComputeOutliers(size_t total_size, double expansion, AbstractMethod* method) {
+ void ComputeOutliers(size_t total_size, double expansion, mirror::AbstractMethod* method) {
method_outlier_size.push_back(total_size);
method_outlier_expansion.push_back(expansion);
method_outlier.push_back(method);
diff --git a/src/oatexec.cc b/src/oatexec.cc
index ede4799..c05266c 100644
--- a/src/oatexec.cc
+++ b/src/oatexec.cc
@@ -23,7 +23,7 @@
#include "base/logging.h"
#include "jni.h"
-#include "object.h"
+#include "modifiers.h"
#include "ScopedLocalRef.h"
#include "toStringArray.h"
#include "UniquePtr.h"
diff --git a/src/object.cc b/src/object.cc
deleted file mode 100644
index 10bf672..0000000
--- a/src/object.cc
+++ /dev/null
@@ -1,1828 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "object.h"
-
-#include <string.h>
-
-#include <algorithm>
-#include <iostream>
-#include <string>
-#include <utility>
-
-#include "base/logging.h"
-#include "class_linker.h"
-#include "class_loader.h"
-#include "dex_cache.h"
-#include "dex_file.h"
-#include "globals.h"
-#include "heap.h"
-#include "intern_table.h"
-#include "interpreter/interpreter.h"
-#include "monitor.h"
-#include "object_utils.h"
-#include "runtime.h"
-#include "runtime_support.h"
-#include "sirt_ref.h"
-#include "stack.h"
-#include "utils.h"
-#include "well_known_classes.h"
-
-namespace art {
-
-BooleanArray* Object::AsBooleanArray() {
- DCHECK(GetClass()->IsArrayClass());
- DCHECK(GetClass()->GetComponentType()->IsPrimitiveBoolean());
- return down_cast<BooleanArray*>(this);
-}
-
-ByteArray* Object::AsByteArray() {
- DCHECK(GetClass()->IsArrayClass());
- DCHECK(GetClass()->GetComponentType()->IsPrimitiveByte());
- return down_cast<ByteArray*>(this);
-}
-
-CharArray* Object::AsCharArray() {
- DCHECK(GetClass()->IsArrayClass());
- DCHECK(GetClass()->GetComponentType()->IsPrimitiveChar());
- return down_cast<CharArray*>(this);
-}
-
-ShortArray* Object::AsShortArray() {
- DCHECK(GetClass()->IsArrayClass());
- DCHECK(GetClass()->GetComponentType()->IsPrimitiveShort());
- return down_cast<ShortArray*>(this);
-}
-
-IntArray* Object::AsIntArray() {
- DCHECK(GetClass()->IsArrayClass());
- DCHECK(GetClass()->GetComponentType()->IsPrimitiveInt() ||
- GetClass()->GetComponentType()->IsPrimitiveFloat());
- return down_cast<IntArray*>(this);
-}
-
-LongArray* Object::AsLongArray() {
- DCHECK(GetClass()->IsArrayClass());
- DCHECK(GetClass()->GetComponentType()->IsPrimitiveLong() ||
- GetClass()->GetComponentType()->IsPrimitiveDouble());
- return down_cast<LongArray*>(this);
-}
-
-String* Object::AsString() {
- DCHECK(GetClass()->IsStringClass());
- return down_cast<String*>(this);
-}
-
-Throwable* Object::AsThrowable() {
- DCHECK(GetClass()->IsThrowableClass());
- return down_cast<Throwable*>(this);
-}
-
-Object* Object::Clone(Thread* self) {
- Class* c = GetClass();
- DCHECK(!c->IsClassClass());
-
- // Object::SizeOf gets the right size even if we're an array.
- // Using c->AllocObject() here would be wrong.
- size_t num_bytes = SizeOf();
- Heap* heap = Runtime::Current()->GetHeap();
- SirtRef<Object> copy(self, heap->AllocObject(self, c, num_bytes));
- if (copy.get() == NULL) {
- return NULL;
- }
-
- // Copy instance data. We assume memcpy copies by words.
- // TODO: expose and use move32.
- byte* src_bytes = reinterpret_cast<byte*>(this);
- byte* dst_bytes = reinterpret_cast<byte*>(copy.get());
- size_t offset = sizeof(Object);
- memcpy(dst_bytes + offset, src_bytes + offset, num_bytes - offset);
-
- // Perform write barriers on copied object references.
- if (c->IsArrayClass()) {
- if (!c->GetComponentType()->IsPrimitive()) {
- const ObjectArray<Object>* array = copy->AsObjectArray<Object>();
- heap->WriteBarrierArray(copy.get(), 0, array->GetLength());
- }
- } else {
- for (const Class* klass = c; klass != NULL; klass = klass->GetSuperClass()) {
- size_t num_reference_fields = klass->NumReferenceInstanceFields();
- for (size_t i = 0; i < num_reference_fields; ++i) {
- Field* field = klass->GetInstanceField(i);
- MemberOffset field_offset = field->GetOffset();
- const Object* ref = copy->GetFieldObject<const Object*>(field_offset, false);
- heap->WriteBarrierField(copy.get(), field_offset, ref);
- }
- }
- }
-
- if (c->IsFinalizable()) {
- heap->AddFinalizerReference(Thread::Current(), copy.get());
- }
-
- return copy.get();
-}
-
-uint32_t Object::GetThinLockId() {
- return Monitor::GetThinLockId(monitor_);
-}
-
-void Object::MonitorEnter(Thread* thread) {
- Monitor::MonitorEnter(thread, this);
-}
-
-bool Object::MonitorExit(Thread* thread) {
- return Monitor::MonitorExit(thread, this);
-}
-
-void Object::Notify() {
- Monitor::Notify(Thread::Current(), this);
-}
-
-void Object::NotifyAll() {
- Monitor::NotifyAll(Thread::Current(), this);
-}
-
-void Object::Wait() {
- Monitor::Wait(Thread::Current(), this, 0, 0, true, kWaiting);
-}
-
-void Object::Wait(int64_t ms, int32_t ns) {
- Monitor::Wait(Thread::Current(), this, ms, ns, true, kTimedWaiting);
-}
-
-#if VERIFY_OBJECT_ENABLED
-void Object::CheckFieldAssignment(MemberOffset field_offset, const Object* new_value) {
- const Class* c = GetClass();
- if (Runtime::Current()->GetClassLinker() == NULL ||
- !Runtime::Current()->GetHeap()->IsObjectValidationEnabled() ||
- !c->IsResolved()) {
- return;
- }
- for (const Class* cur = c; cur != NULL; cur = cur->GetSuperClass()) {
- ObjectArray<Field>* fields = cur->GetIFields();
- if (fields != NULL) {
- size_t num_ref_ifields = cur->NumReferenceInstanceFields();
- for (size_t i = 0; i < num_ref_ifields; ++i) {
- Field* field = fields->Get(i);
- if (field->GetOffset().Int32Value() == field_offset.Int32Value()) {
- FieldHelper fh(field);
- CHECK(fh.GetType()->IsAssignableFrom(new_value->GetClass()));
- return;
- }
- }
- }
- }
- if (c->IsArrayClass()) {
- // Bounds and assign-ability done in the array setter.
- return;
- }
- if (IsClass()) {
- ObjectArray<Field>* fields = AsClass()->GetSFields();
- if (fields != NULL) {
- size_t num_ref_sfields = AsClass()->NumReferenceStaticFields();
- for (size_t i = 0; i < num_ref_sfields; ++i) {
- Field* field = fields->Get(i);
- if (field->GetOffset().Int32Value() == field_offset.Int32Value()) {
- FieldHelper fh(field);
- CHECK(fh.GetType()->IsAssignableFrom(new_value->GetClass()));
- return;
- }
- }
- }
- }
- LOG(FATAL) << "Failed to find field for assignment to " << reinterpret_cast<void*>(this)
- << " of type " << PrettyDescriptor(c) << " at offset " << field_offset;
-}
-#endif
-
-// TODO: get global references for these
-Class* Field::java_lang_reflect_Field_ = NULL;
-
-void Field::SetClass(Class* java_lang_reflect_Field) {
- CHECK(java_lang_reflect_Field_ == NULL);
- CHECK(java_lang_reflect_Field != NULL);
- java_lang_reflect_Field_ = java_lang_reflect_Field;
-}
-
-void Field::ResetClass() {
- CHECK(java_lang_reflect_Field_ != NULL);
- java_lang_reflect_Field_ = NULL;
-}
-
-void Field::SetOffset(MemberOffset num_bytes) {
- DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
-#if 0 // TODO enable later in boot and under !NDEBUG
- FieldHelper fh(this);
- Primitive::Type type = fh.GetTypeAsPrimitiveType();
- if (type == Primitive::kPrimDouble || type == Primitive::kPrimLong) {
- DCHECK_ALIGNED(num_bytes.Uint32Value(), 8);
- }
-#endif
- SetField32(OFFSET_OF_OBJECT_MEMBER(Field, offset_), num_bytes.Uint32Value(), false);
-}
-
-uint32_t Field::Get32(const Object* object) const {
- DCHECK(object != NULL) << PrettyField(this);
- DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
- return object->GetField32(GetOffset(), IsVolatile());
-}
-
-void Field::Set32(Object* object, uint32_t new_value) const {
- DCHECK(object != NULL) << PrettyField(this);
- DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
- object->SetField32(GetOffset(), new_value, IsVolatile());
-}
-
-uint64_t Field::Get64(const Object* object) const {
- DCHECK(object != NULL) << PrettyField(this);
- DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
- return object->GetField64(GetOffset(), IsVolatile());
-}
-
-void Field::Set64(Object* object, uint64_t new_value) const {
- DCHECK(object != NULL) << PrettyField(this);
- DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
- object->SetField64(GetOffset(), new_value, IsVolatile());
-}
-
-Object* Field::GetObj(const Object* object) const {
- DCHECK(object != NULL) << PrettyField(this);
- DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
- return object->GetFieldObject<Object*>(GetOffset(), IsVolatile());
-}
-
-void Field::SetObj(Object* object, const Object* new_value) const {
- DCHECK(object != NULL) << PrettyField(this);
- DCHECK(!IsStatic() || (object == GetDeclaringClass()) || !Runtime::Current()->IsStarted());
- object->SetFieldObject(GetOffset(), new_value, IsVolatile());
-}
-
-bool Field::GetBoolean(const Object* object) const {
- DCHECK_EQ(Primitive::kPrimBoolean, FieldHelper(this).GetTypeAsPrimitiveType())
- << PrettyField(this);
- return Get32(object);
-}
-
-void Field::SetBoolean(Object* object, bool z) const {
- DCHECK_EQ(Primitive::kPrimBoolean, FieldHelper(this).GetTypeAsPrimitiveType())
- << PrettyField(this);
- Set32(object, z);
-}
-
-int8_t Field::GetByte(const Object* object) const {
- DCHECK_EQ(Primitive::kPrimByte, FieldHelper(this).GetTypeAsPrimitiveType())
- << PrettyField(this);
- return Get32(object);
-}
-
-void Field::SetByte(Object* object, int8_t b) const {
- DCHECK_EQ(Primitive::kPrimByte, FieldHelper(this).GetTypeAsPrimitiveType())
- << PrettyField(this);
- Set32(object, b);
-}
-
-uint16_t Field::GetChar(const Object* object) const {
- DCHECK_EQ(Primitive::kPrimChar, FieldHelper(this).GetTypeAsPrimitiveType())
- << PrettyField(this);
- return Get32(object);
-}
-
-void Field::SetChar(Object* object, uint16_t c) const {
- DCHECK_EQ(Primitive::kPrimChar, FieldHelper(this).GetTypeAsPrimitiveType())
- << PrettyField(this);
- Set32(object, c);
-}
-
-int16_t Field::GetShort(const Object* object) const {
- DCHECK_EQ(Primitive::kPrimShort, FieldHelper(this).GetTypeAsPrimitiveType())
- << PrettyField(this);
- return Get32(object);
-}
-
-void Field::SetShort(Object* object, int16_t s) const {
- DCHECK_EQ(Primitive::kPrimShort, FieldHelper(this).GetTypeAsPrimitiveType())
- << PrettyField(this);
- Set32(object, s);
-}
-
-int32_t Field::GetInt(const Object* object) const {
-#ifndef NDEBUG
- Primitive::Type type = FieldHelper(this).GetTypeAsPrimitiveType();
- CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
-#endif
- return Get32(object);
-}
-
-void Field::SetInt(Object* object, int32_t i) const {
-#ifndef NDEBUG
- Primitive::Type type = FieldHelper(this).GetTypeAsPrimitiveType();
- CHECK(type == Primitive::kPrimInt || type == Primitive::kPrimFloat) << PrettyField(this);
-#endif
- Set32(object, i);
-}
-
-int64_t Field::GetLong(const Object* object) const {
-#ifndef NDEBUG
- Primitive::Type type = FieldHelper(this).GetTypeAsPrimitiveType();
- CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
-#endif
- return Get64(object);
-}
-
-void Field::SetLong(Object* object, int64_t j) const {
-#ifndef NDEBUG
- Primitive::Type type = FieldHelper(this).GetTypeAsPrimitiveType();
- CHECK(type == Primitive::kPrimLong || type == Primitive::kPrimDouble) << PrettyField(this);
-#endif
- Set64(object, j);
-}
-
-union Bits {
- jdouble d;
- jfloat f;
- jint i;
- jlong j;
-};
-
-float Field::GetFloat(const Object* object) const {
- DCHECK_EQ(Primitive::kPrimFloat, FieldHelper(this).GetTypeAsPrimitiveType())
- << PrettyField(this);
- Bits bits;
- bits.i = Get32(object);
- return bits.f;
-}
-
-void Field::SetFloat(Object* object, float f) const {
- DCHECK_EQ(Primitive::kPrimFloat, FieldHelper(this).GetTypeAsPrimitiveType())
- << PrettyField(this);
- Bits bits;
- bits.f = f;
- Set32(object, bits.i);
-}
-
-double Field::GetDouble(const Object* object) const {
- DCHECK_EQ(Primitive::kPrimDouble, FieldHelper(this).GetTypeAsPrimitiveType())
- << PrettyField(this);
- Bits bits;
- bits.j = Get64(object);
- return bits.d;
-}
-
-void Field::SetDouble(Object* object, double d) const {
- DCHECK_EQ(Primitive::kPrimDouble, FieldHelper(this).GetTypeAsPrimitiveType())
- << PrettyField(this);
- Bits bits;
- bits.d = d;
- Set64(object, bits.j);
-}
-
-Object* Field::GetObject(const Object* object) const {
- DCHECK_EQ(Primitive::kPrimNot, FieldHelper(this).GetTypeAsPrimitiveType())
- << PrettyField(this);
- return GetObj(object);
-}
-
-void Field::SetObject(Object* object, const Object* l) const {
- DCHECK_EQ(Primitive::kPrimNot, FieldHelper(this).GetTypeAsPrimitiveType())
- << PrettyField(this);
- SetObj(object, l);
-}
-
-// TODO: get global references for these
-Class* AbstractMethod::java_lang_reflect_Constructor_ = NULL;
-Class* AbstractMethod::java_lang_reflect_Method_ = NULL;
-
-InvokeType AbstractMethod::GetInvokeType() const {
- // TODO: kSuper?
- if (GetDeclaringClass()->IsInterface()) {
- return kInterface;
- } else if (IsStatic()) {
- return kStatic;
- } else if (IsDirect()) {
- return kDirect;
- } else {
- return kVirtual;
- }
-}
-
-void AbstractMethod::SetClasses(Class* java_lang_reflect_Constructor, Class* java_lang_reflect_Method) {
- CHECK(java_lang_reflect_Constructor_ == NULL);
- CHECK(java_lang_reflect_Constructor != NULL);
- java_lang_reflect_Constructor_ = java_lang_reflect_Constructor;
-
- CHECK(java_lang_reflect_Method_ == NULL);
- CHECK(java_lang_reflect_Method != NULL);
- java_lang_reflect_Method_ = java_lang_reflect_Method;
-}
-
-void AbstractMethod::ResetClasses() {
- CHECK(java_lang_reflect_Constructor_ != NULL);
- java_lang_reflect_Constructor_ = NULL;
-
- CHECK(java_lang_reflect_Method_ != NULL);
- java_lang_reflect_Method_ = NULL;
-}
-
-ObjectArray<String>* AbstractMethod::GetDexCacheStrings() const {
- return GetFieldObject<ObjectArray<String>*>(
- OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_strings_), false);
-}
-
-void AbstractMethod::SetDexCacheStrings(ObjectArray<String>* new_dex_cache_strings) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_strings_),
- new_dex_cache_strings, false);
-}
-
-ObjectArray<AbstractMethod>* AbstractMethod::GetDexCacheResolvedMethods() const {
- return GetFieldObject<ObjectArray<AbstractMethod>*>(
- OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_resolved_methods_), false);
-}
-
-void AbstractMethod::SetDexCacheResolvedMethods(ObjectArray<AbstractMethod>* new_dex_cache_methods) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_resolved_methods_),
- new_dex_cache_methods, false);
-}
-
-ObjectArray<Class>* AbstractMethod::GetDexCacheResolvedTypes() const {
- return GetFieldObject<ObjectArray<Class>*>(
- OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_resolved_types_), false);
-}
-
-void AbstractMethod::SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cache_classes) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_resolved_types_),
- new_dex_cache_classes, false);
-}
-
-ObjectArray<StaticStorageBase>* AbstractMethod::GetDexCacheInitializedStaticStorage() const {
- return GetFieldObject<ObjectArray<StaticStorageBase>*>(
- OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_initialized_static_storage_),
- false);
-}
-
-void AbstractMethod::SetDexCacheInitializedStaticStorage(ObjectArray<StaticStorageBase>* new_value) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_initialized_static_storage_),
- new_value, false);
-}
-
-size_t AbstractMethod::NumArgRegisters(const StringPiece& shorty) {
- CHECK_LE(1, shorty.length());
- uint32_t num_registers = 0;
- for (int i = 1; i < shorty.length(); ++i) {
- char ch = shorty[i];
- if (ch == 'D' || ch == 'J') {
- num_registers += 2;
- } else {
- num_registers += 1;
- }
- }
- return num_registers;
-}
-
-bool AbstractMethod::IsProxyMethod() const {
- return GetDeclaringClass()->IsProxyClass();
-}
-
-AbstractMethod* AbstractMethod::FindOverriddenMethod() const {
- if (IsStatic()) {
- return NULL;
- }
- Class* declaring_class = GetDeclaringClass();
- Class* super_class = declaring_class->GetSuperClass();
- uint16_t method_index = GetMethodIndex();
- ObjectArray<AbstractMethod>* super_class_vtable = super_class->GetVTable();
- AbstractMethod* result = NULL;
- // Did this method override a super class method? If so load the result from the super class'
- // vtable
- if (super_class_vtable != NULL && method_index < super_class_vtable->GetLength()) {
- result = super_class_vtable->Get(method_index);
- } else {
- // Method didn't override superclass method so search interfaces
- if (IsProxyMethod()) {
- result = GetDexCacheResolvedMethods()->Get(GetDexMethodIndex());
- CHECK_EQ(result,
- Runtime::Current()->GetClassLinker()->FindMethodForProxy(GetDeclaringClass(), this));
- } else {
- MethodHelper mh(this);
- MethodHelper interface_mh;
- IfTable* iftable = GetDeclaringClass()->GetIfTable();
- for (size_t i = 0; i < iftable->Count() && result == NULL; i++) {
- Class* interface = iftable->GetInterface(i);
- for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
- AbstractMethod* interface_method = interface->GetVirtualMethod(j);
- interface_mh.ChangeMethod(interface_method);
- if (mh.HasSameNameAndSignature(&interface_mh)) {
- result = interface_method;
- break;
- }
- }
- }
- }
- }
-#ifndef NDEBUG
- MethodHelper result_mh(result);
- DCHECK(result == NULL || MethodHelper(this).HasSameNameAndSignature(&result_mh));
-#endif
- return result;
-}
-
-static const void* GetOatCode(const AbstractMethod* m)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Runtime* runtime = Runtime::Current();
- const void* code = m->GetCode();
- // Peel off any method tracing trampoline.
- if (runtime->IsMethodTracingActive() && runtime->GetInstrumentation()->GetSavedCodeFromMap(m) != NULL) {
- code = runtime->GetInstrumentation()->GetSavedCodeFromMap(m);
- }
- // Peel off any resolution stub.
- if (code == runtime->GetResolutionStubArray(Runtime::kStaticMethod)->GetData()) {
- code = runtime->GetClassLinker()->GetOatCodeFor(m);
- }
- return code;
-}
-
-uintptr_t AbstractMethod::NativePcOffset(const uintptr_t pc) const {
- return pc - reinterpret_cast<uintptr_t>(GetOatCode(this));
-}
-
-// Find the lowest-address native safepoint pc for a given dex pc
-uintptr_t AbstractMethod::ToFirstNativeSafepointPc(const uint32_t dex_pc) const {
-#if !defined(ART_USE_LLVM_COMPILER)
- const uint32_t* mapping_table = GetPcToDexMappingTable();
- if (mapping_table == NULL) {
- DCHECK(IsNative() || IsCalleeSaveMethod() || IsProxyMethod()) << PrettyMethod(this);
- return DexFile::kDexNoIndex; // Special no mapping case
- }
- size_t mapping_table_length = GetPcToDexMappingTableLength();
- for (size_t i = 0; i < mapping_table_length; i += 2) {
- if (mapping_table[i + 1] == dex_pc) {
- return mapping_table[i] + reinterpret_cast<uintptr_t>(GetOatCode(this));
- }
- }
- LOG(FATAL) << "Failed to find native offset for dex pc 0x" << std::hex << dex_pc
- << " in " << PrettyMethod(this);
- return 0;
-#else
- // Compiler LLVM doesn't use the machine pc, we just use dex pc instead.
- return static_cast<uint32_t>(dex_pc);
-#endif
-}
-
-uint32_t AbstractMethod::ToDexPc(const uintptr_t pc) const {
-#if !defined(ART_USE_LLVM_COMPILER)
- const uint32_t* mapping_table = GetPcToDexMappingTable();
- if (mapping_table == NULL) {
- DCHECK(IsNative() || IsCalleeSaveMethod() || IsProxyMethod()) << PrettyMethod(this);
- return DexFile::kDexNoIndex; // Special no mapping case
- }
- size_t mapping_table_length = GetPcToDexMappingTableLength();
- uint32_t sought_offset = pc - reinterpret_cast<uintptr_t>(GetOatCode(this));
- for (size_t i = 0; i < mapping_table_length; i += 2) {
- if (mapping_table[i] == sought_offset) {
- return mapping_table[i + 1];
- }
- }
- LOG(ERROR) << "Failed to find Dex offset for PC offset " << reinterpret_cast<void*>(sought_offset)
- << "(PC " << reinterpret_cast<void*>(pc) << ") in " << PrettyMethod(this);
- return DexFile::kDexNoIndex;
-#else
- // Compiler LLVM doesn't use the machine pc, we just use dex pc instead.
- return static_cast<uint32_t>(pc);
-#endif
-}
-
-uintptr_t AbstractMethod::ToNativePc(const uint32_t dex_pc) const {
- const uint32_t* mapping_table = GetDexToPcMappingTable();
- if (mapping_table == NULL) {
- DCHECK_EQ(dex_pc, 0U);
- return 0; // Special no mapping/pc == 0 case
- }
- size_t mapping_table_length = GetDexToPcMappingTableLength();
- for (size_t i = 0; i < mapping_table_length; i += 2) {
- uint32_t map_offset = mapping_table[i];
- uint32_t map_dex_offset = mapping_table[i + 1];
- if (map_dex_offset == dex_pc) {
- return reinterpret_cast<uintptr_t>(GetOatCode(this)) + map_offset;
- }
- }
- LOG(FATAL) << "Looking up Dex PC not contained in method, 0x" << std::hex << dex_pc
- << " in " << PrettyMethod(this);
- return 0;
-}
-
-uint32_t AbstractMethod::FindCatchBlock(Class* exception_type, uint32_t dex_pc) const {
- MethodHelper mh(this);
- const DexFile::CodeItem* code_item = mh.GetCodeItem();
- // Iterate over the catch handlers associated with dex_pc
- for (CatchHandlerIterator it(*code_item, dex_pc); it.HasNext(); it.Next()) {
- uint16_t iter_type_idx = it.GetHandlerTypeIndex();
- // Catch all case
- if (iter_type_idx == DexFile::kDexNoIndex16) {
- return it.GetHandlerAddress();
- }
- // Does this catch exception type apply?
- Class* iter_exception_type = mh.GetDexCacheResolvedType(iter_type_idx);
- if (iter_exception_type == NULL) {
- // The verifier should take care of resolving all exception classes early
- LOG(WARNING) << "Unresolved exception class when finding catch block: "
- << mh.GetTypeDescriptorFromTypeIdx(iter_type_idx);
- } else if (iter_exception_type->IsAssignableFrom(exception_type)) {
- return it.GetHandlerAddress();
- }
- }
- // Handler not found
- return DexFile::kDexNoIndex;
-}
-
-void AbstractMethod::Invoke(Thread* self, Object* receiver, JValue* args, JValue* result) {
- if (kIsDebugBuild) {
- self->AssertThreadSuspensionIsAllowable();
- CHECK_EQ(kRunnable, self->GetState());
- }
-
- // Push a transition back into managed code onto the linked list in thread.
- ManagedStack fragment;
- self->PushManagedStackFragment(&fragment);
-
- // Call the invoke stub associated with the method.
- // Pass everything as arguments.
- AbstractMethod::InvokeStub* stub = GetInvokeStub();
-
- if (UNLIKELY(!Runtime::Current()->IsStarted())){
- LOG(INFO) << "Not invoking " << PrettyMethod(this) << " for a runtime that isn't started";
- if (result != NULL) {
- result->SetJ(0);
- }
- } else {
- bool interpret = self->ReadFlag(kEnterInterpreter) && !IsNative() && !IsProxyMethod();
- const bool kLogInvocationStartAndReturn = false;
- if (!interpret && GetCode() != NULL && stub != NULL) {
- if (kLogInvocationStartAndReturn) {
- LOG(INFO) << StringPrintf("Invoking '%s' code=%p stub=%p",
- PrettyMethod(this).c_str(), GetCode(), stub);
- }
- (*stub)(this, receiver, self, args, result);
- if (kLogInvocationStartAndReturn) {
- LOG(INFO) << StringPrintf("Returned '%s' code=%p stub=%p",
- PrettyMethod(this).c_str(), GetCode(), stub);
- }
- } else {
- const bool kInterpretMethodsWithNoCode = false;
- if (interpret || kInterpretMethodsWithNoCode) {
- if (kLogInvocationStartAndReturn) {
- LOG(INFO) << "Interpreting " << PrettyMethod(this) << "'";
- }
- art::interpreter::EnterInterpreterFromInvoke(self, this, receiver, args, result);
- if (kLogInvocationStartAndReturn) {
- LOG(INFO) << "Returned '" << PrettyMethod(this) << "'";
- }
- } else {
- LOG(INFO) << "Not invoking '" << PrettyMethod(this)
- << "' code=" << reinterpret_cast<const void*>(GetCode())
- << " stub=" << reinterpret_cast<void*>(stub);
- if (result != NULL) {
- result->SetJ(0);
- }
- }
- }
- }
-
- // Pop transition.
- self->PopManagedStackFragment(fragment);
-}
-
-bool AbstractMethod::IsRegistered() const {
- void* native_method = GetFieldPtr<void*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, native_method_), false);
- CHECK(native_method != NULL);
- void* jni_stub = Runtime::Current()->GetJniDlsymLookupStub()->GetData();
- return native_method != jni_stub;
-}
-
-void AbstractMethod::RegisterNative(Thread* self, const void* native_method) {
- DCHECK(Thread::Current() == self);
- CHECK(IsNative()) << PrettyMethod(this);
- CHECK(native_method != NULL) << PrettyMethod(this);
-#if defined(ART_USE_LLVM_COMPILER)
- SetFieldPtr<const void*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, native_method_),
- native_method, false);
-#else
- if (!self->GetJniEnv()->vm->work_around_app_jni_bugs) {
- SetFieldPtr<const void*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, native_method_),
- native_method, false);
- } else {
- // We've been asked to associate this method with the given native method but are working
- // around JNI bugs, that include not giving Object** SIRT references to native methods. Direct
- // the native method to runtime support and store the target somewhere runtime support will
- // find it.
-#if defined(__arm__)
- SetFieldPtr<const void*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, native_method_),
- reinterpret_cast<const void*>(art_work_around_app_jni_bugs), false);
-#else
- UNIMPLEMENTED(FATAL);
-#endif
- SetFieldPtr<const uint8_t*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, native_gc_map_),
- reinterpret_cast<const uint8_t*>(native_method), false);
- }
-#endif
-}
-
-void AbstractMethod::UnregisterNative(Thread* self) {
- CHECK(IsNative()) << PrettyMethod(this);
- // restore stub to lookup native pointer via dlsym
- RegisterNative(self, Runtime::Current()->GetJniDlsymLookupStub()->GetData());
-}
-
-Class* Class::java_lang_Class_ = NULL;
-
-void Class::SetClassClass(Class* java_lang_Class) {
- CHECK(java_lang_Class_ == NULL) << java_lang_Class_ << " " << java_lang_Class;
- CHECK(java_lang_Class != NULL);
- java_lang_Class_ = java_lang_Class;
-}
-
-void Class::ResetClass() {
- CHECK(java_lang_Class_ != NULL);
- java_lang_Class_ = NULL;
-}
-
-void Class::SetStatus(Status new_status) {
- CHECK(new_status > GetStatus() || new_status == kStatusError || !Runtime::Current()->IsStarted())
- << PrettyClass(this) << " " << GetStatus() << " -> " << new_status;
- CHECK(sizeof(Status) == sizeof(uint32_t)) << PrettyClass(this);
- if (new_status > kStatusResolved) {
- CHECK_EQ(GetThinLockId(), Thread::Current()->GetThinLockId()) << PrettyClass(this);
- }
- if (new_status == kStatusError) {
- CHECK_NE(GetStatus(), kStatusError) << PrettyClass(this);
-
- // stash current exception
- Thread* self = Thread::Current();
- SirtRef<Throwable> exception(self, self->GetException());
- CHECK(exception.get() != NULL);
-
- // clear exception to call FindSystemClass
- self->ClearException();
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Class* eiie_class = class_linker->FindSystemClass("Ljava/lang/ExceptionInInitializerError;");
- CHECK(!self->IsExceptionPending());
-
- // only verification errors, not initialization problems, should set a verify error.
- // this is to ensure that ThrowEarlierClassFailure will throw NoClassDefFoundError in that case.
- Class* exception_class = exception->GetClass();
- if (!eiie_class->IsAssignableFrom(exception_class)) {
- SetVerifyErrorClass(exception_class);
- }
-
- // restore exception
- self->SetException(exception.get());
- }
- return SetField32(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status, false);
-}
-
-DexCache* Class::GetDexCache() const {
- return GetFieldObject<DexCache*>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), false);
-}
-
-void Class::SetDexCache(DexCache* new_dex_cache) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache, false);
-}
-
-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(self, this, this->object_size_);
-}
-
-void Class::SetClassSize(size_t new_class_size) {
- DCHECK_GE(new_class_size, GetClassSize()) << " class=" << PrettyTypeOf(this);
- SetField32(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), new_class_size, false);
-}
-
-// Return the class' name. The exact format is bizarre, but it's the specified behavior for
-// Class.getName: keywords for primitive types, regular "[I" form for primitive arrays (so "int"
-// but "[I"), and arrays of reference types written between "L" and ";" but with dots rather than
-// slashes (so "java.lang.String" but "[Ljava.lang.String;"). Madness.
-String* Class::ComputeName() {
- String* name = GetName();
- if (name != NULL) {
- return name;
- }
- std::string descriptor(ClassHelper(this).GetDescriptor());
- if ((descriptor[0] != 'L') && (descriptor[0] != '[')) {
- // The descriptor indicates that this is the class for
- // a primitive type; special-case the return value.
- const char* c_name = NULL;
- switch (descriptor[0]) {
- case 'Z': c_name = "boolean"; break;
- case 'B': c_name = "byte"; break;
- case 'C': c_name = "char"; break;
- case 'S': c_name = "short"; break;
- case 'I': c_name = "int"; break;
- case 'J': c_name = "long"; break;
- case 'F': c_name = "float"; break;
- case 'D': c_name = "double"; break;
- case 'V': c_name = "void"; break;
- default:
- LOG(FATAL) << "Unknown primitive type: " << PrintableChar(descriptor[0]);
- }
- 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.
- if (descriptor.size() > 2 && descriptor[0] == 'L' && descriptor[descriptor.size() - 1] == ';') {
- descriptor.erase(0, 1);
- descriptor.erase(descriptor.size() - 1);
- }
- std::replace(descriptor.begin(), descriptor.end(), '/', '.');
- name = String::AllocFromModifiedUtf8(Thread::Current(), descriptor.c_str());
- }
- SetName(name);
- return name;
-}
-
-void Class::DumpClass(std::ostream& os, int flags) const {
- if ((flags & kDumpClassFullDetail) == 0) {
- os << PrettyClass(this);
- if ((flags & kDumpClassClassLoader) != 0) {
- os << ' ' << GetClassLoader();
- }
- if ((flags & kDumpClassInitialized) != 0) {
- os << ' ' << GetStatus();
- }
- os << "\n";
- return;
- }
-
- Class* super = GetSuperClass();
- ClassHelper kh(this);
- os << "----- " << (IsInterface() ? "interface" : "class") << " "
- << "'" << kh.GetDescriptor() << "' cl=" << GetClassLoader() << " -----\n",
- os << " objectSize=" << SizeOf() << " "
- << "(" << (super != NULL ? super->SizeOf() : -1) << " from super)\n",
- os << StringPrintf(" access=0x%04x.%04x\n",
- GetAccessFlags() >> 16, GetAccessFlags() & kAccJavaFlagsMask);
- if (super != NULL) {
- os << " super='" << PrettyClass(super) << "' (cl=" << super->GetClassLoader() << ")\n";
- }
- if (IsArrayClass()) {
- os << " componentType=" << PrettyClass(GetComponentType()) << "\n";
- }
- if (kh.NumDirectInterfaces() > 0) {
- os << " interfaces (" << kh.NumDirectInterfaces() << "):\n";
- for (size_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
- Class* interface = kh.GetDirectInterface(i);
- const ClassLoader* cl = interface->GetClassLoader();
- os << StringPrintf(" %2zd: %s (cl=%p)\n", i, PrettyClass(interface).c_str(), cl);
- }
- }
- os << " vtable (" << NumVirtualMethods() << " entries, "
- << (super != NULL ? super->NumVirtualMethods() : 0) << " in super):\n";
- for (size_t i = 0; i < NumVirtualMethods(); ++i) {
- os << StringPrintf(" %2zd: %s\n", i, PrettyMethod(GetVirtualMethodDuringLinking(i)).c_str());
- }
- os << " direct methods (" << NumDirectMethods() << " entries):\n";
- for (size_t i = 0; i < NumDirectMethods(); ++i) {
- os << StringPrintf(" %2zd: %s\n", i, PrettyMethod(GetDirectMethod(i)).c_str());
- }
- if (NumStaticFields() > 0) {
- os << " static fields (" << NumStaticFields() << " entries):\n";
- if (IsResolved() || IsErroneous()) {
- for (size_t i = 0; i < NumStaticFields(); ++i) {
- os << StringPrintf(" %2zd: %s\n", i, PrettyField(GetStaticField(i)).c_str());
- }
- } else {
- os << " <not yet available>";
- }
- }
- if (NumInstanceFields() > 0) {
- os << " instance fields (" << NumInstanceFields() << " entries):\n";
- if (IsResolved() || IsErroneous()) {
- for (size_t i = 0; i < NumInstanceFields(); ++i) {
- os << StringPrintf(" %2zd: %s\n", i, PrettyField(GetInstanceField(i)).c_str());
- }
- } else {
- os << " <not yet available>";
- }
- }
-}
-
-void Class::SetReferenceInstanceOffsets(uint32_t new_reference_offsets) {
- if (new_reference_offsets != CLASS_WALK_SUPER) {
- // Sanity check that the number of bits set in the reference offset bitmap
- // agrees with the number of references
- size_t count = 0;
- for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
- count += c->NumReferenceInstanceFieldsDuringLinking();
- }
- CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets), count);
- }
- SetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_),
- new_reference_offsets, false);
-}
-
-void Class::SetReferenceStaticOffsets(uint32_t new_reference_offsets) {
- if (new_reference_offsets != CLASS_WALK_SUPER) {
- // Sanity check that the number of bits set in the reference offset bitmap
- // agrees with the number of references
- CHECK_EQ((size_t)__builtin_popcount(new_reference_offsets),
- NumReferenceStaticFieldsDuringLinking());
- }
- SetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_static_offsets_),
- new_reference_offsets, false);
-}
-
-bool Class::Implements(const Class* klass) const {
- DCHECK(klass != NULL);
- DCHECK(klass->IsInterface()) << PrettyClass(this);
- // All interfaces implemented directly and by our superclass, and
- // recursively all super-interfaces of those interfaces, are listed
- // in iftable_, so we can just do a linear scan through that.
- int32_t iftable_count = GetIfTableCount();
- IfTable* iftable = GetIfTable();
- for (int32_t i = 0; i < iftable_count; i++) {
- if (iftable->GetInterface(i) == klass) {
- return true;
- }
- }
- return false;
-}
-
-// Determine whether "this" is assignable from "src", where both of these
-// are array classes.
-//
-// Consider an array class, e.g. Y[][], where Y is a subclass of X.
-// Y[][] = Y[][] --> true (identity)
-// X[][] = Y[][] --> true (element superclass)
-// Y = Y[][] --> false
-// Y[] = Y[][] --> false
-// Object = Y[][] --> true (everything is an object)
-// Object[] = Y[][] --> true
-// Object[][] = Y[][] --> true
-// Object[][][] = Y[][] --> false (too many []s)
-// Serializable = Y[][] --> true (all arrays are Serializable)
-// Serializable[] = Y[][] --> true
-// Serializable[][] = Y[][] --> false (unless Y is Serializable)
-//
-// Don't forget about primitive types.
-// Object[] = int[] --> false
-//
-bool Class::IsArrayAssignableFromArray(const Class* src) const {
- DCHECK(IsArrayClass()) << PrettyClass(this);
- DCHECK(src->IsArrayClass()) << PrettyClass(src);
- return GetComponentType()->IsAssignableFrom(src->GetComponentType());
-}
-
-bool Class::IsAssignableFromArray(const Class* src) const {
- DCHECK(!IsInterface()) << PrettyClass(this); // handled first in IsAssignableFrom
- DCHECK(src->IsArrayClass()) << PrettyClass(src);
- if (!IsArrayClass()) {
- // If "this" is not also an array, it must be Object.
- // src's super should be java_lang_Object, since it is an array.
- Class* java_lang_Object = src->GetSuperClass();
- DCHECK(java_lang_Object != NULL) << PrettyClass(src);
- DCHECK(java_lang_Object->GetSuperClass() == NULL) << PrettyClass(src);
- return this == java_lang_Object;
- }
- return IsArrayAssignableFromArray(src);
-}
-
-bool Class::IsSubClass(const Class* klass) const {
- DCHECK(!IsInterface()) << PrettyClass(this);
- DCHECK(!IsArrayClass()) << PrettyClass(this);
- const Class* current = this;
- do {
- if (current == klass) {
- return true;
- }
- current = current->GetSuperClass();
- } while (current != NULL);
- return false;
-}
-
-bool Class::IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2) {
- size_t i = 0;
- while (descriptor1[i] != '\0' && descriptor1[i] == descriptor2[i]) {
- ++i;
- }
- if (descriptor1.find('/', i) != StringPiece::npos ||
- descriptor2.find('/', i) != StringPiece::npos) {
- return false;
- } else {
- return true;
- }
-}
-
-bool Class::IsInSamePackage(const Class* that) const {
- const Class* klass1 = this;
- const Class* klass2 = that;
- if (klass1 == klass2) {
- return true;
- }
- // Class loaders must match.
- if (klass1->GetClassLoader() != klass2->GetClassLoader()) {
- return false;
- }
- // Arrays are in the same package when their element classes are.
- while (klass1->IsArrayClass()) {
- klass1 = klass1->GetComponentType();
- }
- while (klass2->IsArrayClass()) {
- klass2 = klass2->GetComponentType();
- }
- // Compare the package part of the descriptor string.
- ClassHelper kh(klass1);
- std::string descriptor1(kh.GetDescriptor());
- kh.ChangeClass(klass2);
- std::string descriptor2(kh.GetDescriptor());
- return IsInSamePackage(descriptor1, descriptor2);
-}
-
-bool Class::IsClassClass() const {
- Class* java_lang_Class = GetClass()->GetClass();
- return this == java_lang_Class;
-}
-
-bool Class::IsStringClass() const {
- return this == String::GetJavaLangString();
-}
-
-bool Class::IsThrowableClass() const {
- return WellKnownClasses::ToClass(WellKnownClasses::java_lang_Throwable)->IsAssignableFrom(this);
-}
-
-bool Class::IsFieldClass() const {
- Class* java_lang_Class = GetClass();
- Class* java_lang_reflect_Field = java_lang_Class->GetInstanceField(0)->GetClass();
- return this == java_lang_reflect_Field;
-
-}
-
-bool Class::IsMethodClass() const {
- return (this == AbstractMethod::GetMethodClass()) ||
- (this == AbstractMethod::GetConstructorClass());
-
-}
-
-ClassLoader* Class::GetClassLoader() const {
- return GetFieldObject<ClassLoader*>(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), false);
-}
-
-void Class::SetClassLoader(ClassLoader* new_class_loader) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader, false);
-}
-
-AbstractMethod* Class::FindVirtualMethodForInterface(AbstractMethod* method) {
- Class* declaring_class = method->GetDeclaringClass();
- DCHECK(declaring_class != NULL) << PrettyClass(this);
- DCHECK(declaring_class->IsInterface()) << PrettyMethod(method);
- // TODO cache to improve lookup speed
- int32_t iftable_count = GetIfTableCount();
- IfTable* iftable = GetIfTable();
- for (int32_t i = 0; i < iftable_count; i++) {
- if (iftable->GetInterface(i) == declaring_class) {
- return iftable->GetMethodArray(i)->Get(method->GetMethodIndex());
- }
- }
- return NULL;
-}
-
-AbstractMethod* Class::FindInterfaceMethod(const StringPiece& name, const StringPiece& signature) const {
- // Check the current class before checking the interfaces.
- AbstractMethod* method = FindDeclaredVirtualMethod(name, signature);
- if (method != NULL) {
- return method;
- }
-
- int32_t iftable_count = GetIfTableCount();
- IfTable* iftable = GetIfTable();
- for (int32_t i = 0; i < iftable_count; i++) {
- method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(name, signature);
- if (method != NULL) {
- return method;
- }
- }
- return NULL;
-}
-
-AbstractMethod* Class::FindInterfaceMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const {
- // Check the current class before checking the interfaces.
- AbstractMethod* method = FindDeclaredVirtualMethod(dex_cache, dex_method_idx);
- if (method != NULL) {
- return method;
- }
-
- int32_t iftable_count = GetIfTableCount();
- IfTable* iftable = GetIfTable();
- for (int32_t i = 0; i < iftable_count; i++) {
- method = iftable->GetInterface(i)->FindDeclaredVirtualMethod(dex_cache, dex_method_idx);
- if (method != NULL) {
- return method;
- }
- }
- return NULL;
-}
-
-
-AbstractMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const StringPiece& signature) const {
- MethodHelper mh;
- for (size_t i = 0; i < NumDirectMethods(); ++i) {
- AbstractMethod* method = GetDirectMethod(i);
- mh.ChangeMethod(method);
- if (name == mh.GetName() && signature == mh.GetSignature()) {
- return method;
- }
- }
- return NULL;
-}
-
-AbstractMethod* Class::FindDeclaredDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const {
- if (GetDexCache() == dex_cache) {
- for (size_t i = 0; i < NumDirectMethods(); ++i) {
- AbstractMethod* method = GetDirectMethod(i);
- if (method->GetDexMethodIndex() == dex_method_idx) {
- return method;
- }
- }
- }
- return NULL;
-}
-
-AbstractMethod* Class::FindDirectMethod(const StringPiece& name, const StringPiece& signature) const {
- for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
- AbstractMethod* method = klass->FindDeclaredDirectMethod(name, signature);
- if (method != NULL) {
- return method;
- }
- }
- return NULL;
-}
-
-AbstractMethod* Class::FindDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const {
- for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
- AbstractMethod* method = klass->FindDeclaredDirectMethod(dex_cache, dex_method_idx);
- if (method != NULL) {
- return method;
- }
- }
- return NULL;
-}
-
-AbstractMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name,
- const StringPiece& signature) const {
- MethodHelper mh;
- for (size_t i = 0; i < NumVirtualMethods(); ++i) {
- AbstractMethod* method = GetVirtualMethod(i);
- mh.ChangeMethod(method);
- if (name == mh.GetName() && signature == mh.GetSignature()) {
- return method;
- }
- }
- return NULL;
-}
-
-AbstractMethod* Class::FindDeclaredVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const {
- if (GetDexCache() == dex_cache) {
- for (size_t i = 0; i < NumVirtualMethods(); ++i) {
- AbstractMethod* method = GetVirtualMethod(i);
- if (method->GetDexMethodIndex() == dex_method_idx) {
- return method;
- }
- }
- }
- return NULL;
-}
-
-AbstractMethod* Class::FindVirtualMethod(const StringPiece& name, const StringPiece& signature) const {
- for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
- AbstractMethod* method = klass->FindDeclaredVirtualMethod(name, signature);
- if (method != NULL) {
- return method;
- }
- }
- return NULL;
-}
-
-AbstractMethod* Class::FindVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const {
- for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
- AbstractMethod* method = klass->FindDeclaredVirtualMethod(dex_cache, dex_method_idx);
- if (method != NULL) {
- return method;
- }
- }
- return NULL;
-}
-
-Field* Class::FindDeclaredInstanceField(const StringPiece& name, const StringPiece& type) {
- // Is the field in this class?
- // Interfaces are not relevant because they can't contain instance fields.
- FieldHelper fh;
- for (size_t i = 0; i < NumInstanceFields(); ++i) {
- Field* f = GetInstanceField(i);
- fh.ChangeField(f);
- if (name == fh.GetName() && type == fh.GetTypeDescriptor()) {
- return f;
- }
- }
- return NULL;
-}
-
-Field* Class::FindDeclaredInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx) {
- if (GetDexCache() == dex_cache) {
- for (size_t i = 0; i < NumInstanceFields(); ++i) {
- Field* f = GetInstanceField(i);
- if (f->GetDexFieldIndex() == dex_field_idx) {
- return f;
- }
- }
- }
- return NULL;
-}
-
-Field* Class::FindInstanceField(const StringPiece& name, const StringPiece& type) {
- // Is the field in this class, or any of its superclasses?
- // Interfaces are not relevant because they can't contain instance fields.
- for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
- Field* f = c->FindDeclaredInstanceField(name, type);
- if (f != NULL) {
- return f;
- }
- }
- return NULL;
-}
-
-Field* Class::FindInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx) {
- // Is the field in this class, or any of its superclasses?
- // Interfaces are not relevant because they can't contain instance fields.
- for (Class* c = this; c != NULL; c = c->GetSuperClass()) {
- Field* f = c->FindDeclaredInstanceField(dex_cache, dex_field_idx);
- if (f != NULL) {
- return f;
- }
- }
- return NULL;
-}
-
-Field* Class::FindDeclaredStaticField(const StringPiece& name, const StringPiece& type) {
- DCHECK(type != NULL);
- FieldHelper fh;
- for (size_t i = 0; i < NumStaticFields(); ++i) {
- Field* f = GetStaticField(i);
- fh.ChangeField(f);
- if (name == fh.GetName() && type == fh.GetTypeDescriptor()) {
- return f;
- }
- }
- return NULL;
-}
-
-Field* Class::FindDeclaredStaticField(const DexCache* dex_cache, uint32_t dex_field_idx) {
- if (dex_cache == GetDexCache()) {
- for (size_t i = 0; i < NumStaticFields(); ++i) {
- Field* f = GetStaticField(i);
- if (f->GetDexFieldIndex() == dex_field_idx) {
- return f;
- }
- }
- }
- return NULL;
-}
-
-Field* Class::FindStaticField(const StringPiece& name, const StringPiece& type) {
- // Is the field in this class (or its interfaces), or any of its
- // superclasses (or their interfaces)?
- ClassHelper kh;
- for (Class* k = this; k != NULL; k = k->GetSuperClass()) {
- // Is the field in this class?
- Field* f = k->FindDeclaredStaticField(name, type);
- if (f != NULL) {
- return f;
- }
- // Is this field in any of this class' interfaces?
- kh.ChangeClass(k);
- for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
- Class* interface = kh.GetDirectInterface(i);
- f = interface->FindStaticField(name, type);
- if (f != NULL) {
- return f;
- }
- }
- }
- return NULL;
-}
-
-Field* Class::FindStaticField(const DexCache* dex_cache, uint32_t dex_field_idx) {
- ClassHelper kh;
- for (Class* k = this; k != NULL; k = k->GetSuperClass()) {
- // Is the field in this class?
- Field* f = k->FindDeclaredStaticField(dex_cache, dex_field_idx);
- if (f != NULL) {
- return f;
- }
- // Is this field in any of this class' interfaces?
- kh.ChangeClass(k);
- for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
- Class* interface = kh.GetDirectInterface(i);
- f = interface->FindStaticField(dex_cache, dex_field_idx);
- if (f != NULL) {
- return f;
- }
- }
- }
- return NULL;
-}
-
-Field* Class::FindField(const StringPiece& name, const StringPiece& type) {
- // Find a field using the JLS field resolution order
- ClassHelper kh;
- for (Class* k = this; k != NULL; k = k->GetSuperClass()) {
- // Is the field in this class?
- Field* f = k->FindDeclaredInstanceField(name, type);
- if (f != NULL) {
- return f;
- }
- f = k->FindDeclaredStaticField(name, type);
- if (f != NULL) {
- return f;
- }
- // Is this field in any of this class' interfaces?
- kh.ChangeClass(k);
- for (uint32_t i = 0; i < kh.NumDirectInterfaces(); ++i) {
- Class* interface = kh.GetDirectInterface(i);
- f = interface->FindStaticField(name, type);
- if (f != NULL) {
- return f;
- }
- }
- }
- return NULL;
-}
-
-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());
-
- size_t header_size = sizeof(Object) + (component_size == sizeof(int64_t) ? 8 : 4);
- size_t data_size = component_count * component_size;
- size_t size = header_size + data_size;
-
- // 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) {
- 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(self, array_class, size));
- if (array != NULL) {
- DCHECK(array->IsArrayInstance());
- array->SetLength(component_count);
- }
- return array;
-}
-
-Array* Array::Alloc(Thread* self, Class* array_class, int32_t component_count) {
- DCHECK(array_class->IsArrayClass());
- return Alloc(self, array_class, component_count, array_class->GetComponentSize());
-}
-
-// Create a multi-dimensional array of Objects or primitive types.
-//
-// We have to generate the names for X[], X[][], X[][][], and so on. The
-// easiest way to deal with that is to create the full name once and then
-// subtract pieces off. Besides, we want to start with the outermost
-// piece and work our way in.
-// Recursively create an array with multiple dimensions. Elements may be
-// Objects or primitive types.
-static Array* RecursiveCreateMultiArray(Thread* self, Class* array_class, int current_dimension,
- IntArray* dimensions)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- int32_t array_length = dimensions->Get(current_dimension);
- SirtRef<Array> new_array(self, Array::Alloc(self, array_class, array_length));
- if (UNLIKELY(new_array.get() == NULL)) {
- CHECK(self->IsExceptionPending());
- return NULL;
- }
- if ((current_dimension + 1) < dimensions->GetLength()) {
- // Create a new sub-array in every element of the array.
- for (int32_t i = 0; i < array_length; i++) {
- Array* sub_array = RecursiveCreateMultiArray(self, array_class->GetComponentType(),
- current_dimension + 1, dimensions);
- if (UNLIKELY(sub_array == NULL)) {
- CHECK(self->IsExceptionPending());
- return NULL;
- }
- new_array->AsObjectArray<Array>()->Set(i, sub_array);
- }
- }
- return new_array.get();
-}
-
-Array* Array::CreateMultiArray(Thread* self, Class* element_class, IntArray* dimensions) {
- // Verify dimensions.
- //
- // The caller is responsible for verifying that "dimArray" is non-null
- // and has a length > 0 and <= 255.
- int num_dimensions = dimensions->GetLength();
- DCHECK_GT(num_dimensions, 0);
- DCHECK_LE(num_dimensions, 255);
-
- for (int i = 0; i < num_dimensions; i++) {
- int dimension = dimensions->Get(i);
- if (UNLIKELY(dimension < 0)) {
- self->ThrowNewExceptionF("Ljava/lang/NegativeArraySizeException;",
- "Dimension %d: %d", i, dimension);
- return NULL;
- }
- }
-
- // Generate the full name of the array class.
- std::string descriptor(num_dimensions, '[');
- descriptor += ClassHelper(element_class).GetDescriptor();
-
- // Find/generate the array class.
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Class* array_class = class_linker->FindClass(descriptor.c_str(), element_class->GetClassLoader());
- if (UNLIKELY(array_class == NULL)) {
- CHECK(self->IsExceptionPending());
- return NULL;
- }
- // create the array
- Array* new_array = RecursiveCreateMultiArray(self, array_class, 0, dimensions);
- if (UNLIKELY(new_array == NULL)) {
- CHECK(self->IsExceptionPending());
- return NULL;
- }
- return new_array;
-}
-
-bool Array::ThrowArrayIndexOutOfBoundsException(int32_t index) const {
- Thread::Current()->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;",
- "length=%i; index=%i", length_, index);
- return false;
-}
-
-bool Array::ThrowArrayStoreException(Object* object) const {
- Thread::Current()->ThrowNewExceptionF("Ljava/lang/ArrayStoreException;",
- "%s cannot be stored in an array of type %s",
- PrettyTypeOf(object).c_str(), PrettyTypeOf(this).c_str());
- return false;
-}
-
-template<typename T>
-PrimitiveArray<T>* PrimitiveArray<T>::Alloc(Thread* self, size_t length) {
- DCHECK(array_class_ != NULL);
- Array* raw_array = Array::Alloc(self, array_class_, length, sizeof(T));
- return down_cast<PrimitiveArray<T>*>(raw_array);
-}
-
-template <typename T> Class* PrimitiveArray<T>::array_class_ = NULL;
-
-// Explicitly instantiate all the primitive array types.
-template class PrimitiveArray<uint8_t>; // BooleanArray
-template class PrimitiveArray<int8_t>; // ByteArray
-template class PrimitiveArray<uint16_t>; // CharArray
-template class PrimitiveArray<double>; // DoubleArray
-template class PrimitiveArray<float>; // FloatArray
-template class PrimitiveArray<int32_t>; // IntArray
-template class PrimitiveArray<int64_t>; // LongArray
-template class PrimitiveArray<int16_t>; // ShortArray
-
-// Explicitly instantiate Class[][]
-template class ObjectArray<ObjectArray<Class> >;
-
-// TODO: get global references for these
-Class* String::java_lang_String_ = NULL;
-
-void String::SetClass(Class* java_lang_String) {
- CHECK(java_lang_String_ == NULL);
- CHECK(java_lang_String != NULL);
- java_lang_String_ = java_lang_String;
-}
-
-void String::ResetClass() {
- CHECK(java_lang_String_ != NULL);
- java_lang_String_ = NULL;
-}
-
-String* String::Intern() {
- return Runtime::Current()->GetInternTable()->InternWeak(this);
-}
-
-int32_t String::GetHashCode() {
- int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
- if (result == 0) {
- ComputeHashCode();
- }
- result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false);
- DCHECK(result != 0 || ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()) == 0)
- << ToModifiedUtf8() << " " << result;
- return result;
-}
-
-int32_t String::GetLength() const {
- int32_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(String, count_), false);
- DCHECK(result >= 0 && result <= GetCharArray()->GetLength());
- return result;
-}
-
-uint16_t String::CharAt(int32_t index) const {
- // TODO: do we need this? Equals is the only caller, and could
- // bounds check itself.
- if (index < 0 || index >= count_) {
- Thread* self = Thread::Current();
- self->ThrowNewExceptionF("Ljava/lang/StringIndexOutOfBoundsException;",
- "length=%i; index=%i", count_, index);
- return 0;
- }
- return GetCharArray()->Get(index + GetOffset());
-}
-
-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(self, GetJavaLangString(), utf16_length);
- if (string == NULL) {
- return NULL;
- }
- // TODO: use 16-bit wide memset variant
- CharArray* array = const_cast<CharArray*>(string->GetCharArray());
- if (array == NULL) {
- return NULL;
- }
- for (int i = 0; i < utf16_length; i++) {
- array->Set(i, utf16_data_in[i]);
- }
- if (hash_code != 0) {
- string->SetHashCode(hash_code);
- } else {
- string->ComputeHashCode();
- }
- return string;
-}
-
- String* String::AllocFromModifiedUtf8(Thread* self, const char* utf) {
- if (utf == NULL) {
- return NULL;
- }
- size_t char_count = CountModifiedUtf8Chars(utf);
- return AllocFromModifiedUtf8(self, char_count, utf);
-}
-
-String* String::AllocFromModifiedUtf8(Thread* self, int32_t utf16_length,
- const char* utf8_data_in) {
- String* string = Alloc(self, GetJavaLangString(), utf16_length);
- if (string == NULL) {
- return NULL;
- }
- uint16_t* utf16_data_out =
- const_cast<uint16_t*>(string->GetCharArray()->GetData());
- ConvertModifiedUtf8ToUtf16(utf16_data_out, utf8_data_in);
- string->ComputeHashCode();
- return string;
-}
-
-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(self, java_lang_String, array.get());
-}
-
-String* String::Alloc(Thread* self, Class* java_lang_String, CharArray* array) {
- // Hold reference in case AllocObject causes GC.
- SirtRef<CharArray> array_ref(self, array);
- String* string = down_cast<String*>(java_lang_String->AllocObject(self));
- if (string == NULL) {
- return NULL;
- }
- string->SetArray(array);
- string->SetCount(array->GetLength());
- return string;
-}
-
-bool String::Equals(const String* that) const {
- if (this == that) {
- // Quick reference equality test
- return true;
- } else if (that == NULL) {
- // Null isn't an instanceof anything
- return false;
- } else if (this->GetLength() != that->GetLength()) {
- // Quick length inequality test
- return false;
- } else {
- // Note: don't short circuit on hash code as we're presumably here as the
- // hash code was already equal
- for (int32_t i = 0; i < that->GetLength(); ++i) {
- if (this->CharAt(i) != that->CharAt(i)) {
- return false;
- }
- }
- return true;
- }
-}
-
-bool String::Equals(const uint16_t* that_chars, int32_t that_offset, int32_t that_length) const {
- if (this->GetLength() != that_length) {
- return false;
- } else {
- for (int32_t i = 0; i < that_length; ++i) {
- if (this->CharAt(i) != that_chars[that_offset + i]) {
- return false;
- }
- }
- return true;
- }
-}
-
-bool String::Equals(const char* modified_utf8) const {
- for (int32_t i = 0; i < GetLength(); ++i) {
- uint16_t ch = GetUtf16FromUtf8(&modified_utf8);
- if (ch == '\0' || ch != CharAt(i)) {
- return false;
- }
- }
- return *modified_utf8 == '\0';
-}
-
-bool String::Equals(const StringPiece& modified_utf8) const {
- if (modified_utf8.size() != GetLength()) {
- return false;
- }
- const char* p = modified_utf8.data();
- for (int32_t i = 0; i < GetLength(); ++i) {
- uint16_t ch = GetUtf16FromUtf8(&p);
- if (ch != CharAt(i)) {
- return false;
- }
- }
- return true;
-}
-
-// Create a modified UTF-8 encoded std::string from a java/lang/String object.
-std::string String::ToModifiedUtf8() const {
- const uint16_t* chars = GetCharArray()->GetData() + GetOffset();
- size_t byte_count = GetUtfLength();
- std::string result(byte_count, static_cast<char>(0));
- ConvertUtf16ToModifiedUtf8(&result[0], chars, GetLength());
- return result;
-}
-
-#ifdef HAVE__MEMCMP16
-// "count" is in 16-bit units.
-extern "C" uint32_t __memcmp16(const uint16_t* s0, const uint16_t* s1, size_t count);
-#define MemCmp16 __memcmp16
-#else
-static uint32_t MemCmp16(const uint16_t* s0, const uint16_t* s1, size_t count) {
- for (size_t i = 0; i < count; i++) {
- if (s0[i] != s1[i]) {
- return static_cast<int32_t>(s0[i]) - static_cast<int32_t>(s1[i]);
- }
- }
- return 0;
-}
-#endif
-
-int32_t String::CompareTo(String* rhs) const {
- // Quick test for comparison of a string with itself.
- const String* lhs = this;
- if (lhs == rhs) {
- return 0;
- }
- // TODO: is this still true?
- // The annoying part here is that 0x00e9 - 0xffff != 0x00ea,
- // because the interpreter converts the characters to 32-bit integers
- // *without* sign extension before it subtracts them (which makes some
- // sense since "char" is unsigned). So what we get is the result of
- // 0x000000e9 - 0x0000ffff, which is 0xffff00ea.
- int lhsCount = lhs->GetLength();
- int rhsCount = rhs->GetLength();
- int countDiff = lhsCount - rhsCount;
- int minCount = (countDiff < 0) ? lhsCount : rhsCount;
- const uint16_t* lhsChars = lhs->GetCharArray()->GetData() + lhs->GetOffset();
- const uint16_t* rhsChars = rhs->GetCharArray()->GetData() + rhs->GetOffset();
- int otherRes = MemCmp16(lhsChars, rhsChars, minCount);
- if (otherRes != 0) {
- return otherRes;
- }
- return countDiff;
-}
-
-void Throwable::SetCause(Throwable* cause) {
- CHECK(cause != NULL);
- CHECK(cause != this);
- CHECK(GetFieldObject<Throwable*>(OFFSET_OF_OBJECT_MEMBER(Throwable, cause_), false) == NULL);
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Throwable, cause_), cause, false);
-}
-
-bool Throwable::IsCheckedException() const {
- if (InstanceOf(WellKnownClasses::ToClass(WellKnownClasses::java_lang_Error))) {
- return false;
- }
- return !InstanceOf(WellKnownClasses::ToClass(WellKnownClasses::java_lang_RuntimeException));
-}
-
-std::string Throwable::Dump() const {
- std::string result(PrettyTypeOf(this));
- result += ": ";
- String* msg = GetDetailMessage();
- if (msg != NULL) {
- result += msg->ToModifiedUtf8();
- }
- result += "\n";
- Object* stack_state = GetStackState();
- // check stack state isn't missing or corrupt
- if (stack_state != NULL && stack_state->IsObjectArray()) {
- // Decode the internal stack trace into the depth and method trace
- ObjectArray<Object>* method_trace = down_cast<ObjectArray<Object>*>(stack_state);
- int32_t depth = method_trace->GetLength() - 1;
- IntArray* pc_trace = down_cast<IntArray*>(method_trace->Get(depth));
- MethodHelper mh;
- for (int32_t i = 0; i < depth; ++i) {
- AbstractMethod* method = down_cast<AbstractMethod*>(method_trace->Get(i));
- mh.ChangeMethod(method);
- uint32_t dex_pc = pc_trace->Get(i);
- int32_t line_number = mh.GetLineNumFromDexPC(dex_pc);
- const char* source_file = mh.GetDeclaringClassSourceFile();
- result += StringPrintf(" at %s (%s:%d)\n", PrettyMethod(method, true).c_str(),
- source_file, line_number);
- }
- }
- Throwable* cause = GetFieldObject<Throwable*>(OFFSET_OF_OBJECT_MEMBER(Throwable, cause_), false);
- if (cause != NULL && cause != this) { // Constructor makes cause == this by default.
- result += "Caused by: ";
- result += cause->Dump();
- }
- return result;
-}
-
-
-Class* Throwable::java_lang_Throwable_ = NULL;
-
-void Throwable::SetClass(Class* java_lang_Throwable) {
- CHECK(java_lang_Throwable_ == NULL);
- CHECK(java_lang_Throwable != NULL);
- java_lang_Throwable_ = java_lang_Throwable;
-}
-
-void Throwable::ResetClass() {
- CHECK(java_lang_Throwable_ != NULL);
- java_lang_Throwable_ = NULL;
-}
-
-Class* StackTraceElement::java_lang_StackTraceElement_ = NULL;
-
-void StackTraceElement::SetClass(Class* java_lang_StackTraceElement) {
- CHECK(java_lang_StackTraceElement_ == NULL);
- CHECK(java_lang_StackTraceElement != NULL);
- java_lang_StackTraceElement_ = java_lang_StackTraceElement;
-}
-
-void StackTraceElement::ResetClass() {
- CHECK(java_lang_StackTraceElement_ != NULL);
- java_lang_StackTraceElement_ = NULL;
-}
-
-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(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_),
- const_cast<String*>(method_name), false);
- trace->SetFieldObject(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, file_name_),
- const_cast<String*>(file_name), false);
- trace->SetField32(OFFSET_OF_OBJECT_MEMBER(StackTraceElement, line_number_),
- line_number, false);
- return trace;
-}
-
-} // namespace art
diff --git a/src/object.h b/src/object.h
deleted file mode 100644
index f02e312..0000000
--- a/src/object.h
+++ /dev/null
@@ -1,2748 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_OBJECT_H_
-#define ART_SRC_OBJECT_H_
-
-#include <iosfwd>
-#include <vector>
-
-#include "atomic.h"
-#include "base/casts.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/stringpiece.h"
-#include "globals.h"
-#include "heap.h"
-#include "invoke_type.h"
-#include "modifiers.h"
-#include "offsets.h"
-#include "primitive.h"
-#include "runtime.h"
-#include "thread.h"
-#include "UniquePtr.h"
-#include "utf.h"
-
-namespace art {
-
-class Array;
-class Class;
-class ClassLoader;
-class CodeAndDirectMethods;
-class DexCache;
-class Field;
-class IfTable;
-class Monitor;
-class Member;
-class AbstractMethod;
-class Object;
-class StaticStorageBase;
-class String;
-template<class T> class ObjectArray;
-template<class T> class PrimitiveArray;
-typedef PrimitiveArray<uint8_t> BooleanArray;
-typedef PrimitiveArray<int8_t> ByteArray;
-typedef PrimitiveArray<uint16_t> CharArray;
-typedef PrimitiveArray<double> DoubleArray;
-typedef PrimitiveArray<float> FloatArray;
-typedef PrimitiveArray<int32_t> IntArray;
-typedef PrimitiveArray<int64_t> LongArray;
-typedef PrimitiveArray<int16_t> ShortArray;
-union JValue;
-
-#if defined(ART_USE_LLVM_COMPILER)
-namespace compiler_llvm {
- class InferredRegCategoryMap;
-} // namespace compiler_llvm
-#endif
-
-/*
- * Definitions for packing refOffsets in Class.
- */
-/*
- * A magic value for refOffsets. Ignore the bits and walk the super
- * chain when this is the value.
- * [This is an unlikely "natural" value, since it would be 30 non-ref instance
- * fields followed by 2 ref instance fields.]
- */
-#define CLASS_WALK_SUPER ((unsigned int)(3))
-#define CLASS_BITS_PER_WORD (sizeof(unsigned long int) * 8)
-#define CLASS_OFFSET_ALIGNMENT 4
-#define CLASS_HIGH_BIT ((unsigned int)1 << (CLASS_BITS_PER_WORD - 1))
-/*
- * Given an offset, return the bit number which would encode that offset.
- * Local use only.
- */
-#define _CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset) \
- ((unsigned int)(byteOffset) / \
- CLASS_OFFSET_ALIGNMENT)
-/*
- * Is the given offset too large to be encoded?
- */
-#define CLASS_CAN_ENCODE_OFFSET(byteOffset) \
- (_CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset) < CLASS_BITS_PER_WORD)
-/*
- * Return a single bit, encoding the offset.
- * Undefined if the offset is too large, as defined above.
- */
-#define CLASS_BIT_FROM_OFFSET(byteOffset) \
- (CLASS_HIGH_BIT >> _CLASS_BIT_NUMBER_FROM_OFFSET(byteOffset))
-/*
- * Return an offset, given a bit number as returned from CLZ.
- */
-#define CLASS_OFFSET_FROM_CLZ(rshift) \
- MemberOffset((static_cast<int>(rshift) * CLASS_OFFSET_ALIGNMENT))
-
-#define OFFSET_OF_OBJECT_MEMBER(type, field) \
- MemberOffset(OFFSETOF_MEMBER(type, field))
-
-// Classes shared with the managed side of the world need to be packed
-// so that they don't have extra platform specific padding.
-#define MANAGED PACKED(4)
-
-// C++ mirror of java.lang.Object
-class MANAGED Object {
- public:
- static MemberOffset ClassOffset() {
- return OFFSET_OF_OBJECT_MEMBER(Object, klass_);
- }
-
- Class* GetClass() const {
- return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Object, klass_), false);
- }
-
- void SetClass(Class* new_klass);
-
- bool InstanceOf(const Class* klass) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- size_t SizeOf() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- Object* Clone(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- int32_t IdentityHashCode() const {
- #ifdef MOVING_GARBAGE_COLLECTOR
- // TODO: we'll need to use the Object's internal concept of identity
- UNIMPLEMENTED(FATAL);
- #endif
- return reinterpret_cast<int32_t>(this);
- }
-
- static MemberOffset MonitorOffset() {
- return OFFSET_OF_OBJECT_MEMBER(Object, monitor_);
- }
-
- volatile int32_t* GetRawLockWordAddress() {
- byte* raw_addr = reinterpret_cast<byte*>(this) +
- OFFSET_OF_OBJECT_MEMBER(Object, monitor_).Int32Value();
- int32_t* word_addr = reinterpret_cast<int32_t*>(raw_addr);
- return const_cast<volatile int32_t*>(word_addr);
- }
-
- uint32_t GetThinLockId();
-
- void MonitorEnter(Thread* thread) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- EXCLUSIVE_LOCK_FUNCTION(monitor_lock_);
-
- bool MonitorExit(Thread* thread) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- UNLOCK_FUNCTION(monitor_lock_);
-
- void Notify() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- void NotifyAll() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- void Wait() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- void Wait(int64_t timeout) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- void Wait(int64_t timeout, int32_t nanos) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- bool IsClass() const;
-
- Class* AsClass() {
- DCHECK(IsClass());
- return down_cast<Class*>(this);
- }
-
- const Class* AsClass() const {
- DCHECK(IsClass());
- return down_cast<const Class*>(this);
- }
-
- bool IsObjectArray() const;
-
- template<class T>
- ObjectArray<T>* AsObjectArray();
-
- template<class T>
- const ObjectArray<T>* AsObjectArray() const;
-
- bool IsArrayInstance() const;
-
- Array* AsArray() {
- DCHECK(IsArrayInstance());
- return down_cast<Array*>(this);
- }
-
- const Array* AsArray() const {
- DCHECK(IsArrayInstance());
- return down_cast<const Array*>(this);
- }
-
- BooleanArray* AsBooleanArray();
- ByteArray* AsByteArray();
- CharArray* AsCharArray();
- ShortArray* AsShortArray();
- IntArray* AsIntArray();
- LongArray* AsLongArray();
-
- String* AsString();
-
- Throwable* AsThrowable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- bool IsMethod() const;
-
- AbstractMethod* AsMethod() {
- DCHECK(IsMethod());
- return down_cast<AbstractMethod*>(this);
- }
-
- const AbstractMethod* AsMethod() const {
- DCHECK(IsMethod());
- return down_cast<const AbstractMethod*>(this);
- }
-
- bool IsField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- Field* AsField() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(IsField());
- return down_cast<Field*>(this);
- }
-
- const Field* AsField() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(IsField());
- return down_cast<const Field*>(this);
- }
-
- bool IsReferenceInstance() const;
-
- bool IsWeakReferenceInstance() const;
-
- bool IsSoftReferenceInstance() const;
-
- bool IsFinalizerReferenceInstance() const;
-
- bool IsPhantomReferenceInstance() const;
-
- // Accessors for Java type fields
- template<class T>
- T GetFieldObject(MemberOffset field_offset, bool is_volatile) const {
- T result = reinterpret_cast<T>(GetField32(field_offset, is_volatile));
- Runtime::Current()->GetHeap()->VerifyObject(result);
- return result;
- }
-
- void SetFieldObject(MemberOffset field_offset, const Object* new_value, bool is_volatile,
- bool this_is_valid = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Runtime::Current()->GetHeap()->VerifyObject(new_value);
- SetField32(field_offset, reinterpret_cast<uint32_t>(new_value), is_volatile, this_is_valid);
- if (new_value != NULL) {
- CheckFieldAssignment(field_offset, new_value);
- Runtime::Current()->GetHeap()->WriteBarrierField(this, field_offset, new_value);
- }
- }
-
- uint32_t GetField32(MemberOffset field_offset, bool is_volatile) const {
- Runtime::Current()->GetHeap()->VerifyObject(this);
- const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
- const int32_t* word_addr = reinterpret_cast<const int32_t*>(raw_addr);
- if (UNLIKELY(is_volatile)) {
- return android_atomic_acquire_load(word_addr);
- } else {
- return *word_addr;
- }
- }
-
- void SetField32(MemberOffset field_offset, uint32_t new_value, bool is_volatile, bool this_is_valid = true) {
- if (this_is_valid) {
- Runtime::Current()->GetHeap()->VerifyObject(this);
- }
- byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
- uint32_t* word_addr = reinterpret_cast<uint32_t*>(raw_addr);
- if (UNLIKELY(is_volatile)) {
- /*
- * TODO: add an android_atomic_synchronization_store() function and
- * use it in the 32-bit volatile set handlers. On some platforms we
- * can use a fast atomic instruction and avoid the barriers.
- */
- ANDROID_MEMBAR_STORE();
- *word_addr = new_value;
- ANDROID_MEMBAR_FULL();
- } else {
- *word_addr = new_value;
- }
- }
-
- uint64_t GetField64(MemberOffset field_offset, bool is_volatile) const {
- Runtime::Current()->GetHeap()->VerifyObject(this);
- const byte* raw_addr = reinterpret_cast<const byte*>(this) + field_offset.Int32Value();
- const int64_t* addr = reinterpret_cast<const int64_t*>(raw_addr);
- if (UNLIKELY(is_volatile)) {
- uint64_t result = QuasiAtomic::Read64(addr);
- ANDROID_MEMBAR_FULL();
- return result;
- } else {
- return *addr;
- }
- }
-
- void SetField64(MemberOffset field_offset, uint64_t new_value, bool is_volatile) {
- Runtime::Current()->GetHeap()->VerifyObject(this);
- byte* raw_addr = reinterpret_cast<byte*>(this) + field_offset.Int32Value();
- int64_t* addr = reinterpret_cast<int64_t*>(raw_addr);
- if (UNLIKELY(is_volatile)) {
- ANDROID_MEMBAR_STORE();
- QuasiAtomic::Write64(addr, new_value);
- // Post-store barrier not required due to use of atomic op or mutex.
- } else {
- *addr = new_value;
- }
- }
-
- protected:
- // Accessors for non-Java type fields
- template<class T>
- T GetFieldPtr(MemberOffset field_offset, bool is_volatile) const {
- return reinterpret_cast<T>(GetField32(field_offset, is_volatile));
- }
-
- template<typename T>
- void SetFieldPtr(MemberOffset field_offset, T new_value, bool is_volatile, bool this_is_valid = true) {
- SetField32(field_offset, reinterpret_cast<uint32_t>(new_value), is_volatile, this_is_valid);
- }
-
- private:
-#if VERIFY_OBJECT_ENABLED
- void CheckFieldAssignment(MemberOffset field_offset, const Object* new_value)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-#else
- void CheckFieldAssignment(MemberOffset, const Object*)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {}
-#endif
-
- Class* klass_;
-
- uint32_t monitor_;
-
- friend class ImageWriter; // for abusing monitor_ directly
- friend struct ObjectOffsets; // for verifying offset information
- DISALLOW_IMPLICIT_CONSTRUCTORS(Object);
-};
-
-// C++ mirror of java.lang.reflect.Field
-class MANAGED Field : public Object {
- public:
- Class* GetDeclaringClass() const;
-
- void SetDeclaringClass(Class *new_declaring_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- uint32_t GetAccessFlags() const;
-
- void SetAccessFlags(uint32_t new_access_flags) {
- SetField32(OFFSET_OF_OBJECT_MEMBER(Field, access_flags_), new_access_flags, false);
- }
-
- bool IsPublic() const {
- return (GetAccessFlags() & kAccPublic) != 0;
- }
-
- bool IsStatic() const {
- return (GetAccessFlags() & kAccStatic) != 0;
- }
-
- bool IsFinal() const {
- return (GetAccessFlags() & kAccFinal) != 0;
- }
-
- uint32_t GetDexFieldIndex() const {
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Field, field_dex_idx_), false);
- }
-
- void SetDexFieldIndex(uint32_t new_idx) {
- SetField32(OFFSET_OF_OBJECT_MEMBER(Field, field_dex_idx_), new_idx, false);
- }
-
- // Offset to field within an Object
- MemberOffset GetOffset() const;
-
- static MemberOffset OffsetOffset() {
- return MemberOffset(OFFSETOF_MEMBER(Field, offset_));
- }
-
- MemberOffset GetOffsetDuringLinking() const;
-
- void SetOffset(MemberOffset num_bytes);
-
- // field access, null object for static fields
- bool GetBoolean(const Object* object) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetBoolean(Object* object, bool z) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- int8_t GetByte(const Object* object) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetByte(Object* object, int8_t b) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- uint16_t GetChar(const Object* object) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetChar(Object* object, uint16_t c) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- int16_t GetShort(const Object* object) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetShort(Object* object, int16_t s) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- int32_t GetInt(const Object* object) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetInt(Object* object, int32_t i) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- int64_t GetLong(const Object* object) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetLong(Object* object, int64_t j) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- float GetFloat(const Object* object) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetFloat(Object* object, float f) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- double GetDouble(const Object* object) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetDouble(Object* object, double d) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Object* GetObject(const Object* object) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetObject(Object* object, const Object* l) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // raw field accesses
- uint32_t Get32(const Object* object) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void Set32(Object* object, uint32_t new_value) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- uint64_t Get64(const Object* object) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void Set64(Object* object, uint64_t new_value) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Object* GetObj(const Object* object) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetObj(Object* object, const Object* new_value) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static Class* GetJavaLangReflectField() {
- DCHECK(java_lang_reflect_Field_ != NULL);
- return java_lang_reflect_Field_;
- }
-
- static void SetClass(Class* java_lang_reflect_Field);
- static void ResetClass();
-
- bool IsVolatile() const {
- return (GetAccessFlags() & kAccVolatile) != 0;
- }
-
- private:
- // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
- // The class we are a part of
- Class* declaring_class_;
-
- uint32_t access_flags_;
-
- // Dex cache index of field id
- uint32_t field_dex_idx_;
-
- // Offset of field within an instance or in the Class' static fields
- uint32_t offset_;
-
- static Class* java_lang_reflect_Field_;
-
- friend struct FieldOffsets; // for verifying offset information
- DISALLOW_IMPLICIT_CONSTRUCTORS(Field);
-};
-
-// C++ mirror of java.lang.reflect.Method and java.lang.reflect.Constructor
-class MANAGED AbstractMethod : public Object {
- public:
- // A function that invokes a method with an array of its arguments.
- typedef void InvokeStub(const AbstractMethod* method,
- Object* obj,
- Thread* thread,
- JValue* args,
- JValue* result);
-
- Class* GetDeclaringClass() const;
-
- void SetDeclaringClass(Class *new_declaring_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static MemberOffset DeclaringClassOffset() {
- return MemberOffset(OFFSETOF_MEMBER(AbstractMethod, declaring_class_));
- }
-
- uint32_t GetAccessFlags() const;
-
- void SetAccessFlags(uint32_t new_access_flags) {
- SetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, access_flags_), new_access_flags, false);
- }
-
- // Approximate what kind of method call would be used for this method.
- InvokeType GetInvokeType() const;
-
- // Returns true if the method is declared public.
- bool IsPublic() const {
- return (GetAccessFlags() & kAccPublic) != 0;
- }
-
- // Returns true if the method is declared private.
- bool IsPrivate() const {
- return (GetAccessFlags() & kAccPrivate) != 0;
- }
-
- // Returns true if the method is declared static.
- bool IsStatic() const {
- return (GetAccessFlags() & kAccStatic) != 0;
- }
-
- // Returns true if the method is a constructor.
- bool IsConstructor() const {
- return (GetAccessFlags() & kAccConstructor) != 0;
- }
-
- // Returns true if the method is static, private, or a constructor.
- bool IsDirect() const {
- return IsDirect(GetAccessFlags());
- }
-
- static bool IsDirect(uint32_t access_flags) {
- return (access_flags & (kAccStatic | kAccPrivate | kAccConstructor)) != 0;
- }
-
- // Returns true if the method is declared synchronized.
- bool IsSynchronized() const {
- uint32_t synchonized = kAccSynchronized | kAccDeclaredSynchronized;
- return (GetAccessFlags() & synchonized) != 0;
- }
-
- bool IsFinal() const {
- return (GetAccessFlags() & kAccFinal) != 0;
- }
-
- bool IsMiranda() const {
- return (GetAccessFlags() & kAccMiranda) != 0;
- }
-
- bool IsNative() const {
- return (GetAccessFlags() & kAccNative) != 0;
- }
-
- bool IsAbstract() const {
- return (GetAccessFlags() & kAccAbstract) != 0;
- }
-
- bool IsSynthetic() const {
- return (GetAccessFlags() & kAccSynthetic) != 0;
- }
-
- bool IsProxyMethod() const;
-
- bool CheckIncompatibleClassChange(InvokeType type);
-
- uint16_t GetMethodIndex() const;
-
- size_t GetVtableIndex() const {
- return GetMethodIndex();
- }
-
- void SetMethodIndex(uint16_t new_method_index) {
- SetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, method_index_), new_method_index, false);
- }
-
- static MemberOffset MethodIndexOffset() {
- return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, method_index_);
- }
-
- uint32_t GetCodeItemOffset() const {
- return GetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, code_item_offset_), false);
- }
-
- void SetCodeItemOffset(uint32_t new_code_off) {
- SetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, code_item_offset_), new_code_off, false);
- }
-
- // Number of 32bit registers that would be required to hold all the arguments
- static size_t NumArgRegisters(const StringPiece& shorty);
-
- uint32_t GetDexMethodIndex() const;
-
- void SetDexMethodIndex(uint32_t new_idx) {
- SetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, method_dex_index_), new_idx, false);
- }
-
- ObjectArray<String>* GetDexCacheStrings() const;
- void SetDexCacheStrings(ObjectArray<String>* new_dex_cache_strings)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static MemberOffset DexCacheStringsOffset() {
- return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_strings_);
- }
-
- static MemberOffset DexCacheResolvedMethodsOffset() {
- return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_resolved_methods_);
- }
-
- static MemberOffset DexCacheResolvedTypesOffset() {
- return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, dex_cache_resolved_types_);
- }
-
- static MemberOffset DexCacheInitializedStaticStorageOffset() {
- return OFFSET_OF_OBJECT_MEMBER(AbstractMethod,
- dex_cache_initialized_static_storage_);
- }
-
- ObjectArray<AbstractMethod>* GetDexCacheResolvedMethods() const;
- void SetDexCacheResolvedMethods(ObjectArray<AbstractMethod>* new_dex_cache_methods)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- ObjectArray<Class>* GetDexCacheResolvedTypes() const;
- void SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cache_types)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- ObjectArray<StaticStorageBase>* GetDexCacheInitializedStaticStorage() const;
- void SetDexCacheInitializedStaticStorage(ObjectArray<StaticStorageBase>* new_value)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Find the method that this method overrides
- AbstractMethod* FindOverriddenMethod() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- void Invoke(Thread* self, Object* receiver, JValue* args, JValue* result)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- const void* GetCode() const {
- return GetFieldPtr<const void*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, code_), false);
- }
-
- void SetCode(const void* code) {
- SetFieldPtr<const void*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, code_), code, false);
- }
-
- uint32_t GetCodeSize() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(!IsRuntimeMethod() && !IsProxyMethod()) << PrettyMethod(this);
- uintptr_t code = reinterpret_cast<uintptr_t>(GetCode());
- if (code == 0) {
- return 0;
- }
- // TODO: make this Thumb2 specific
- code &= ~0x1;
- return reinterpret_cast<uint32_t*>(code)[-1];
- }
-
- bool IsWithinCode(uintptr_t pc) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- uintptr_t code = reinterpret_cast<uintptr_t>(GetCode());
- if (code == 0) {
- return pc == 0;
- }
- /*
- * During a stack walk, a return PC may point to the end of the code + 1
- * (in the case that the last instruction is a call that isn't expected to
- * return. Thus, we check <= code + GetCodeSize().
- */
- return (code <= pc && pc <= code + GetCodeSize());
- }
-
- void AssertPcIsWithinCode(uintptr_t pc) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- uint32_t GetOatCodeOffset() const {
- DCHECK(!Runtime::Current()->IsStarted());
- return reinterpret_cast<uint32_t>(GetCode());
- }
-
- void SetOatCodeOffset(uint32_t code_offset) {
- DCHECK(!Runtime::Current()->IsStarted());
- SetCode(reinterpret_cast<void*>(code_offset));
- }
-
- static MemberOffset GetCodeOffset() {
- return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, code_);
- }
-
- const uint32_t* GetMappingTable() const {
- const uint32_t* map = GetMappingTableRaw();
- if (map == NULL) {
- return map;
- }
- return map + 1;
- }
-
- uint32_t GetPcToDexMappingTableLength() const {
- const uint32_t* map = GetMappingTableRaw();
- if (map == NULL) {
- return 0;
- }
- return map[2];
- }
-
- const uint32_t* GetPcToDexMappingTable() const {
- const uint32_t* map = GetMappingTableRaw();
- if (map == NULL) {
- return map;
- }
- return map + 3;
- }
-
-
- uint32_t GetDexToPcMappingTableLength() const {
- const uint32_t* map = GetMappingTableRaw();
- if (map == NULL) {
- return 0;
- }
- return map[1] - map[2];
- }
-
- const uint32_t* GetDexToPcMappingTable() const {
- const uint32_t* map = GetMappingTableRaw();
- if (map == NULL) {
- return map;
- }
- return map + 3 + map[2];
- }
-
-
- const uint32_t* GetMappingTableRaw() const {
- return GetFieldPtr<const uint32_t*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, mapping_table_), false);
- }
-
- void SetMappingTable(const uint32_t* mapping_table) {
- SetFieldPtr<const uint32_t*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, mapping_table_),
- mapping_table, false);
- }
-
- uint32_t GetOatMappingTableOffset() const {
- DCHECK(!Runtime::Current()->IsStarted());
- return reinterpret_cast<uint32_t>(GetMappingTableRaw());
- }
-
- void SetOatMappingTableOffset(uint32_t mapping_table_offset) {
- DCHECK(!Runtime::Current()->IsStarted());
- SetMappingTable(reinterpret_cast<const uint32_t*>(mapping_table_offset));
- }
-
- // Callers should wrap the uint16_t* in a VmapTable instance for convenient access.
- const uint16_t* GetVmapTableRaw() const {
- return GetFieldPtr<const uint16_t*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, vmap_table_), false);
- }
-
- void SetVmapTable(const uint16_t* vmap_table) {
- SetFieldPtr<const uint16_t*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, vmap_table_), vmap_table, false);
- }
-
- uint32_t GetOatVmapTableOffset() const {
- DCHECK(!Runtime::Current()->IsStarted());
- return reinterpret_cast<uint32_t>(GetVmapTableRaw());
- }
-
- void SetOatVmapTableOffset(uint32_t vmap_table_offset) {
- DCHECK(!Runtime::Current()->IsStarted());
- SetVmapTable(reinterpret_cast<uint16_t*>(vmap_table_offset));
- }
-
- const uint8_t* GetNativeGcMap() const {
- return GetFieldPtr<uint8_t*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, native_gc_map_), false);
- }
- void SetNativeGcMap(const uint8_t* data) {
- SetFieldPtr<const uint8_t*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, native_gc_map_), data,
- false);
- }
-
- // When building the oat need a convenient place to stuff the offset of the native GC map.
- void SetOatNativeGcMapOffset(uint32_t gc_map_offset) {
- DCHECK(!Runtime::Current()->IsStarted());
- SetNativeGcMap(reinterpret_cast<uint8_t*>(gc_map_offset));
- }
-
- uint32_t GetOatNativeGcMapOffset() const {
- DCHECK(!Runtime::Current()->IsStarted());
- return reinterpret_cast<uint32_t>(GetNativeGcMap());
- }
-
- size_t GetFrameSizeInBytes() const {
- DCHECK_EQ(sizeof(size_t), sizeof(uint32_t));
- size_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, frame_size_in_bytes_), false);
- DCHECK_LE(static_cast<size_t>(kStackAlignment), result);
- return result;
- }
-
- void SetFrameSizeInBytes(size_t new_frame_size_in_bytes) {
- DCHECK_EQ(sizeof(size_t), sizeof(uint32_t));
- SetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, frame_size_in_bytes_),
- new_frame_size_in_bytes, false);
- }
-
- size_t GetReturnPcOffsetInBytes() const {
- return GetFrameSizeInBytes() - kPointerSize;
- }
-
- bool IsRegistered() const;
-
- void RegisterNative(Thread* self, const void* native_method)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- void UnregisterNative(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static MemberOffset NativeMethodOffset() {
- return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, native_method_);
- }
-
- const void* GetNativeMethod() const {
- return reinterpret_cast<const void*>(GetField32(NativeMethodOffset(), false));
- }
-
- // Native to managed invocation stub entry point
- InvokeStub* GetInvokeStub() const {
- InvokeStub* result = GetFieldPtr<InvokeStub*>(
- OFFSET_OF_OBJECT_MEMBER(AbstractMethod, invoke_stub_), false);
- // TODO: DCHECK(result != NULL); should be ahead of time compiled
- return result;
- }
-
- void SetInvokeStub(InvokeStub* invoke_stub) {
- SetFieldPtr<InvokeStub*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, invoke_stub_),
- invoke_stub, false);
- }
-
- uint32_t GetInvokeStubSize() const {
- uintptr_t invoke_stub = reinterpret_cast<uintptr_t>(GetInvokeStub());
- if (invoke_stub == 0) {
- return 0;
- }
- // TODO: make this Thumb2 specific
- invoke_stub &= ~0x1;
- return reinterpret_cast<const uint32_t*>(invoke_stub)[-1];
- }
-
- uint32_t GetOatInvokeStubOffset() const {
- DCHECK(!Runtime::Current()->IsStarted());
- return reinterpret_cast<uint32_t>(GetInvokeStub());
- }
-
- void SetOatInvokeStubOffset(uint32_t invoke_stub_offset) {
- DCHECK(!Runtime::Current()->IsStarted());
- SetInvokeStub(reinterpret_cast<InvokeStub*>(invoke_stub_offset));
- }
-
- static MemberOffset GetInvokeStubOffset() {
- return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, invoke_stub_);
- }
-
- static MemberOffset GetMethodIndexOffset() {
- return OFFSET_OF_OBJECT_MEMBER(AbstractMethod, method_index_);
- }
-
- uint32_t GetCoreSpillMask() const {
- return GetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, core_spill_mask_), false);
- }
-
- void SetCoreSpillMask(uint32_t core_spill_mask) {
- // Computed during compilation
- SetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, core_spill_mask_), core_spill_mask, false);
- }
-
- uint32_t GetFpSpillMask() const {
- return GetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, fp_spill_mask_), false);
- }
-
- void SetFpSpillMask(uint32_t fp_spill_mask) {
- // Computed during compilation
- SetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, fp_spill_mask_), fp_spill_mask, false);
- }
-
- // Is this a CalleSaveMethod or ResolutionMethod and therefore doesn't adhere to normal
- // conventions for a method of managed code. Returns false for Proxy methods.
- bool IsRuntimeMethod() const {
- return GetDexMethodIndex() == DexFile::kDexNoIndex16;
- }
-
- // Is this a hand crafted method used for something like describing callee saves?
- bool IsCalleeSaveMethod() const {
- if (!IsRuntimeMethod()) {
- return false;
- }
- Runtime* runtime = Runtime::Current();
- bool result = false;
- for (int i = 0; i < Runtime::kLastCalleeSaveType; i++) {
- if (this == runtime->GetCalleeSaveMethod(Runtime::CalleeSaveType(i))) {
- result = true;
- break;
- }
- }
- return result;
- }
-
- bool IsResolutionMethod() const {
- bool result = this == Runtime::Current()->GetResolutionMethod();
- // Check that if we do think it is phony it looks like the resolution method
- DCHECK(!result || GetDexMethodIndex() == DexFile::kDexNoIndex16);
- return result;
- }
-
- uintptr_t NativePcOffset(const uintptr_t pc) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Converts a native PC to a dex PC.
- uint32_t ToDexPc(const uintptr_t pc) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Converts a dex PC to a native PC.
- uintptr_t ToNativePc(const uint32_t dex_pc) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Converts a dex PC to the first corresponding safepoint PC.
- uintptr_t ToFirstNativeSafepointPc(const uint32_t dex_pc)
- const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Find the catch block for the given exception type and dex_pc
- uint32_t FindCatchBlock(Class* exception_type, uint32_t dex_pc) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static void SetClasses(Class* java_lang_reflect_Constructor, Class* java_lang_reflect_Method);
-
- static Class* GetConstructorClass() {
- return java_lang_reflect_Constructor_;
- }
-
- static Class* GetMethodClass() {
- return java_lang_reflect_Method_;
- }
-
- static void ResetClasses();
-
- protected:
- // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
- // The class we are a part of
- Class* declaring_class_;
-
- // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
- ObjectArray<StaticStorageBase>* dex_cache_initialized_static_storage_;
-
- // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
- ObjectArray<AbstractMethod>* dex_cache_resolved_methods_;
-
- // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
- ObjectArray<Class>* dex_cache_resolved_types_;
-
- // short cuts to declaring_class_->dex_cache_ member for fast compiled code access
- ObjectArray<String>* dex_cache_strings_;
-
- // Access flags; low 16 bits are defined by spec.
- uint32_t access_flags_;
-
- // Compiled code associated with this method for callers from managed code.
- // May be compiled managed code or a bridge for invoking a native method.
- const void* code_;
-
- // Offset to the CodeItem.
- uint32_t code_item_offset_;
-
- // Architecture-dependent register spill mask
- uint32_t core_spill_mask_;
-
- // Architecture-dependent register spill mask
- uint32_t fp_spill_mask_;
-
- // Total size in bytes of the frame
- size_t frame_size_in_bytes_;
-
- // Garbage collection map of native PC offsets to reference bitmaps.
- const uint8_t* native_gc_map_;
-
- // Native invocation stub entry point for calling from native to managed code.
- InvokeStub* invoke_stub_;
-
- // Mapping from native pc to dex pc
- const uint32_t* mapping_table_;
-
- // Index into method_ids of the dex file associated with this method
- uint32_t method_dex_index_;
-
- // For concrete virtual methods, this is the offset of the method in Class::vtable_.
- //
- // For abstract methods in an interface class, this is the offset of the method in
- // "iftable_->Get(n)->GetMethodArray()".
- //
- // For static and direct methods this is the index in the direct methods table.
- uint32_t method_index_;
-
- // The target native method registered with this method
- const void* native_method_;
-
- // When a register is promoted into a register, the spill mask holds which registers hold dex
- // registers. The first promoted register's corresponding dex register is vmap_table_[1], the Nth
- // is vmap_table_[N]. vmap_table_[0] holds the length of the table.
- const uint16_t* vmap_table_;
-
- static Class* java_lang_reflect_Constructor_;
- static Class* java_lang_reflect_Method_;
-
- friend class ImageWriter; // for relocating code_ and invoke_stub_
- friend struct AbstractMethodOffsets; // for verifying offset information
- friend struct ConstructorMethodOffsets; // for verifying offset information
- friend struct MethodOffsets; // for verifying offset information
- DISALLOW_IMPLICIT_CONSTRUCTORS(AbstractMethod);
-};
-
-class MANAGED Method : public AbstractMethod {
-
-};
-
-class MANAGED Constructor : public AbstractMethod {
-
-};
-
-class MANAGED Array : public Object {
- 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(Thread* self, Class* array_class, int32_t component_count)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static Array* Alloc(Thread* self, Class* array_class, int32_t component_count,
- size_t component_size)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static Array* CreateMultiArray(Thread* self, Class* element_class, IntArray* dimensions)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- size_t SizeOf() const;
-
- int32_t GetLength() const {
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Array, length_), false);
- }
-
- void SetLength(int32_t length) {
- CHECK_GE(length, 0);
- SetField32(OFFSET_OF_OBJECT_MEMBER(Array, length_), length, false);
- }
-
- static MemberOffset LengthOffset() {
- return OFFSET_OF_OBJECT_MEMBER(Array, length_);
- }
-
- static MemberOffset DataOffset(size_t component_size) {
- if (component_size != sizeof(int64_t)) {
- return OFFSET_OF_OBJECT_MEMBER(Array, first_element_);
- } else {
- // Align longs and doubles.
- return MemberOffset(OFFSETOF_MEMBER(Array, first_element_) + 4);
- }
- }
-
- void* GetRawData(size_t component_size) {
- intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(component_size).Int32Value();
- return reinterpret_cast<void*>(data);
- }
-
- const void* GetRawData(size_t component_size) const {
- intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(component_size).Int32Value();
- return reinterpret_cast<const void*>(data);
- }
-
- protected:
- bool IsValidIndex(int32_t index) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (UNLIKELY(index < 0 || index >= GetLength())) {
- return ThrowArrayIndexOutOfBoundsException(index);
- }
- return true;
- }
-
- protected:
- bool ThrowArrayIndexOutOfBoundsException(int32_t index) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool ThrowArrayStoreException(Object* object) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- private:
- // The number of array elements.
- int32_t length_;
- // Marker for the data (used by generated code)
- uint32_t first_element_[0];
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(Array);
-};
-
-template<class T>
-class MANAGED ObjectArray : public Array {
- public:
- 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_);
-
- void Set(int32_t i, T* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Set element without bound and element type checks, to be used in limited
- // circumstances, such as during boot image writing
- void SetWithoutChecks(int32_t i, T* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Set element without bound and element type checks, to be used in limited circumstances, such
- // as during boot image writing. Does not do write barrier.
- void SetPtrWithoutChecks(int32_t i, T* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- T* GetWithoutChecks(int32_t i) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static void Copy(const ObjectArray<T>* src, int src_pos,
- ObjectArray<T>* dst, int dst_pos,
- size_t length)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- ObjectArray<T>* CopyOf(Thread* self, int32_t new_length)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(ObjectArray);
-};
-
-template<class T>
-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 {
- return array->AsObjectArray<T>();
- }
-}
-
-template<class T>
-inline T* ObjectArray<T>::Get(int32_t i) const {
- if (UNLIKELY(!IsValidIndex(i))) {
- return NULL;
- }
- MemberOffset data_offset(DataOffset(sizeof(Object*)).Int32Value() + i * sizeof(Object*));
- return GetFieldObject<T*>(data_offset, false);
-}
-
-template<class T>
-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;
-}
-
-class MANAGED IfTable : public ObjectArray<Object> {
- public:
- Class* GetInterface(int32_t i) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Class* interface = Get((i * kMax) + kInterface)->AsClass();
- DCHECK(interface != NULL);
- return interface;
- }
-
- void SetInterface(int32_t i, Class* interface) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- ObjectArray<AbstractMethod>* GetMethodArray(int32_t i) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectArray<AbstractMethod>* method_array =
- down_cast<ObjectArray<AbstractMethod>*>(Get((i * kMax) + kMethodArray));
- DCHECK(method_array != NULL);
- return method_array;
- }
-
- size_t GetMethodArrayCount(int32_t i) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectArray<AbstractMethod>* method_array =
- down_cast<ObjectArray<AbstractMethod>*>(Get((i * kMax) + kMethodArray));
- if (method_array == NULL) {
- return 0;
- }
- return method_array->GetLength();
- }
-
- void SetMethodArray(int32_t i, ObjectArray<AbstractMethod>* new_ma)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(new_ma != NULL);
- DCHECK(Get((i * kMax) + kMethodArray) == NULL);
- Set((i * kMax) + kMethodArray, new_ma);
- }
-
- size_t Count() const {
- return GetLength() / kMax;
- }
-
- enum {
- // Points to the interface class.
- kInterface = 0,
- // Method pointers into the vtable, allow fast map from interface method index to concrete
- // instance method.
- kMethodArray = 1,
- kMax = 2,
- };
-
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(IfTable);
-};
-
-// Type for the InitializedStaticStorage table. Currently the Class
-// provides the static storage. However, this might change to an Array
-// to improve image sharing, so we use this type to avoid assumptions
-// on the current storage.
-class MANAGED StaticStorageBase : public Object {
-};
-
-// C++ mirror of java.lang.Class
-class MANAGED Class : public StaticStorageBase {
- public:
- // Class Status
- //
- // kStatusNotReady: If a Class cannot be found in the class table by
- // FindClass, it allocates an new one with AllocClass in the
- // kStatusNotReady and calls LoadClass. Note if it does find a
- // class, it may not be kStatusResolved and it will try to push it
- // forward toward kStatusResolved.
- //
- // kStatusIdx: LoadClass populates with Class with information from
- // the DexFile, moving the status to kStatusIdx, indicating that the
- // Class value in super_class_ has not been populated. The new Class
- // can then be inserted into the classes table.
- //
- // kStatusLoaded: After taking a lock on Class, the ClassLinker will
- // attempt to move a kStatusIdx class forward to kStatusLoaded by
- // using ResolveClass to initialize the super_class_ and ensuring the
- // interfaces are resolved.
- //
- // kStatusResolved: Still holding the lock on Class, the ClassLinker
- // shows linking is complete and fields of the Class populated by making
- // it kStatusResolved. Java allows circularities of the form where a super
- // class has a field that is of the type of the sub class. We need to be able
- // to fully resolve super classes while resolving types for fields.
- //
- // kStatusRetryVerificationAtRuntime: The verifier sets a class to
- // this state if it encounters a soft failure at compile time. This
- // often happens when there are unresolved classes in other dex
- // files, and this status marks a class as needing to be verified
- // again at runtime.
- //
- // TODO: Explain the other states
- enum Status {
- kStatusError = -1,
- kStatusNotReady = 0,
- kStatusIdx = 1, // Loaded, DEX idx in super_class_type_idx_ and interfaces_type_idx_.
- kStatusLoaded = 2, // DEX idx values resolved.
- kStatusResolved = 3, // Part of linking.
- kStatusVerifying = 4, // In the process of being verified.
- kStatusRetryVerificationAtRuntime = 5, // Compile time verification failed, retry at runtime.
- kStatusVerifyingAtRuntime = 6, // Retrying verification at runtime.
- kStatusVerified = 7, // Logically part of linking; done pre-init.
- kStatusInitializing = 8, // Class init in progress.
- kStatusInitialized = 9, // Ready to go.
- };
-
- Status GetStatus() const {
- DCHECK_EQ(sizeof(Status), sizeof(uint32_t));
- return static_cast<Status>(GetField32(OFFSET_OF_OBJECT_MEMBER(Class, status_), false));
- }
-
- void SetStatus(Status new_status) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Returns true if the class has failed to link.
- bool IsErroneous() const {
- return GetStatus() == kStatusError;
- }
-
- // Returns true if the class has been loaded.
- bool IsIdxLoaded() const {
- return GetStatus() >= kStatusIdx;
- }
-
- // Returns true if the class has been loaded.
- bool IsLoaded() const {
- return GetStatus() >= kStatusLoaded;
- }
-
- // Returns true if the class has been linked.
- bool IsResolved() const {
- return GetStatus() >= kStatusResolved;
- }
-
- // Returns true if the class was compile-time verified.
- bool IsCompileTimeVerified() const {
- return GetStatus() >= kStatusRetryVerificationAtRuntime;
- }
-
- // Returns true if the class has been verified.
- bool IsVerified() const {
- return GetStatus() >= kStatusVerified;
- }
-
- // Returns true if the class is initializing.
- bool IsInitializing() const {
- return GetStatus() >= kStatusInitializing;
- }
-
- // Returns true if the class is initialized.
- bool IsInitialized() const {
- return GetStatus() == kStatusInitialized;
- }
-
- uint32_t GetAccessFlags() const;
-
- void SetAccessFlags(uint32_t new_access_flags) {
- SetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), new_access_flags, false);
- }
-
- // Returns true if the class is an interface.
- bool IsInterface() const {
- return (GetAccessFlags() & kAccInterface) != 0;
- }
-
- // Returns true if the class is declared public.
- bool IsPublic() const {
- return (GetAccessFlags() & kAccPublic) != 0;
- }
-
- // Returns true if the class is declared final.
- bool IsFinal() const {
- return (GetAccessFlags() & kAccFinal) != 0;
- }
-
- bool IsFinalizable() const {
- return (GetAccessFlags() & kAccClassIsFinalizable) != 0;
- }
-
- void SetFinalizable() {
- uint32_t flags = GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), false);
- SetAccessFlags(flags | kAccClassIsFinalizable);
- }
-
- // Returns true if the class is abstract.
- bool IsAbstract() const {
- return (GetAccessFlags() & kAccAbstract) != 0;
- }
-
- // Returns true if the class is an annotation.
- bool IsAnnotation() const {
- return (GetAccessFlags() & kAccAnnotation) != 0;
- }
-
- // Returns true if the class is synthetic.
- bool IsSynthetic() const {
- return (GetAccessFlags() & kAccSynthetic) != 0;
- }
-
- bool IsReferenceClass() const {
- return (GetAccessFlags() & kAccClassIsReference) != 0;
- }
-
- bool IsWeakReferenceClass() const {
- return (GetAccessFlags() & kAccClassIsWeakReference) != 0;
- }
-
- bool IsSoftReferenceClass() const {
- return (GetAccessFlags() & kAccReferenceFlagsMask) == kAccClassIsReference;
- }
-
- bool IsFinalizerReferenceClass() const {
- return (GetAccessFlags() & kAccClassIsFinalizerReference) != 0;
- }
-
- bool IsPhantomReferenceClass() const {
- return (GetAccessFlags() & kAccClassIsPhantomReference) != 0;
- }
-
-
- String* GetName() const; // Returns the cached name.
- void SetName(String* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Sets the cached name.
- // Computes the name, then sets the cached value.
- String* ComputeName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- bool IsProxyClass() const {
- // Read access flags without using getter as whether something is a proxy can be check in
- // any loaded state
- // TODO: switch to a check if the super class is java.lang.reflect.Proxy?
- uint32_t access_flags = GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), false);
- return (access_flags & kAccClassIsProxy) != 0;
- }
-
- Primitive::Type GetPrimitiveType() const {
- DCHECK_EQ(sizeof(Primitive::Type), sizeof(int32_t));
- return static_cast<Primitive::Type>(
- GetField32(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_), false));
- }
-
- void SetPrimitiveType(Primitive::Type new_type) {
- DCHECK_EQ(sizeof(Primitive::Type), sizeof(int32_t));
- SetField32(OFFSET_OF_OBJECT_MEMBER(Class, primitive_type_), new_type, false);
- }
-
- // Returns true if the class is a primitive type.
- bool IsPrimitive() const {
- return GetPrimitiveType() != Primitive::kPrimNot;
- }
-
- bool IsPrimitiveBoolean() const {
- return GetPrimitiveType() == Primitive::kPrimBoolean;
- }
-
- bool IsPrimitiveByte() const {
- return GetPrimitiveType() == Primitive::kPrimByte;
- }
-
- bool IsPrimitiveChar() const {
- return GetPrimitiveType() == Primitive::kPrimChar;
- }
-
- bool IsPrimitiveShort() const {
- return GetPrimitiveType() == Primitive::kPrimShort;
- }
-
- bool IsPrimitiveInt() const {
- return GetPrimitiveType() == Primitive::kPrimInt;
- }
-
- bool IsPrimitiveLong() const {
- return GetPrimitiveType() == Primitive::kPrimLong;
- }
-
- bool IsPrimitiveFloat() const {
- return GetPrimitiveType() == Primitive::kPrimFloat;
- }
-
- bool IsPrimitiveDouble() const {
- return GetPrimitiveType() == Primitive::kPrimDouble;
- }
-
- bool IsPrimitiveVoid() const {
- return GetPrimitiveType() == Primitive::kPrimVoid;
- }
-
- bool IsPrimitiveArray() const {
- return IsArrayClass() && GetComponentType()->IsPrimitive();
- }
-
- // Depth of class from java.lang.Object
- size_t Depth() {
- size_t depth = 0;
- for (Class* klass = this; klass->GetSuperClass() != NULL; klass = klass->GetSuperClass()) {
- depth++;
- }
- return depth;
- }
-
- bool IsArrayClass() const {
- return GetComponentType() != NULL;
- }
-
- bool IsClassClass() const;
-
- bool IsStringClass() const;
-
- bool IsThrowableClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- bool IsFieldClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- bool IsMethodClass() const;
-
- Class* GetComponentType() const {
- return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Class, component_type_), false);
- }
-
- void SetComponentType(Class* new_component_type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(GetComponentType() == NULL);
- DCHECK(new_component_type != NULL);
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, component_type_), new_component_type, false);
- }
-
- size_t GetComponentSize() const {
- return Primitive::ComponentSize(GetComponentType()->GetPrimitiveType());
- }
-
- bool IsObjectClass() const {
- return !IsPrimitive() && GetSuperClass() == NULL;
- }
- bool IsInstantiable() const {
- return !IsPrimitive() && !IsInterface() && !IsAbstract();
- }
-
- bool IsObjectArrayClass() const {
- return GetComponentType() != NULL && !GetComponentType()->IsPrimitive();
- }
-
- // Creates a raw object instance but does not invoke the default constructor.
- 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
- // be used to get their instance size
- return IsClassClass() || IsArrayClass();
- }
-
- size_t SizeOf() const {
- DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), false);
- }
-
- size_t GetClassSize() const {
- DCHECK_EQ(sizeof(size_t), sizeof(uint32_t));
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, class_size_), false);
- }
-
- void SetClassSize(size_t new_class_size)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- size_t GetObjectSize() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- CHECK(!IsVariableSize()) << " class=" << PrettyTypeOf(this);
- DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
- size_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(Class, object_size_), false);
- CHECK_GE(result, sizeof(Object)) << " class=" << PrettyTypeOf(this);
- return result;
- }
-
- void SetObjectSize(size_t new_object_size) {
- DCHECK(!IsVariableSize());
- DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
- return SetField32(OFFSET_OF_OBJECT_MEMBER(Class, object_size_), new_object_size, false);
- }
-
- // Returns true if this class is in the same packages as that class.
- bool IsInSamePackage(const Class* that) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static bool IsInSamePackage(const StringPiece& descriptor1, const StringPiece& descriptor2);
-
- // Returns true if this class can access that class.
- bool CanAccess(Class* that) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return that->IsPublic() || this->IsInSamePackage(that);
- }
-
- // Can this class access a member in the provided class with the provided member access flags?
- // Note that access to the class isn't checked in case the declaring class is protected and the
- // method has been exposed by a public sub-class
- bool CanAccessMember(Class* access_to, uint32_t member_flags) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- // Classes can access all of their own members
- if (this == access_to) {
- return true;
- }
- // Public members are trivially accessible
- if (member_flags & kAccPublic) {
- return true;
- }
- // Private members are trivially not accessible
- if (member_flags & kAccPrivate) {
- return false;
- }
- // Check for protected access from a sub-class, which may or may not be in the same package.
- if (member_flags & kAccProtected) {
- if (this->IsSubClass(access_to)) {
- return true;
- }
- }
- // Allow protected access from other classes in the same package.
- return this->IsInSamePackage(access_to);
- }
-
- bool IsSubClass(const Class* klass) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Can src be assigned to this class? For example, String can be assigned to Object (by an
- // upcast), however, an Object cannot be assigned to a String as a potentially exception throwing
- // downcast would be necessary. Similarly for interfaces, a class that implements (or an interface
- // that extends) another can be assigned to its parent, but not vice-versa. All Classes may assign
- // to themselves. Classes for primitive types may not assign to each other.
- bool IsAssignableFrom(const Class* src) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(src != NULL);
- if (this == src) {
- // Can always assign to things of the same type.
- return true;
- } else if (IsObjectClass()) {
- // Can assign any reference to java.lang.Object.
- return !src->IsPrimitive();
- } else if (IsInterface()) {
- return src->Implements(this);
- } else if (src->IsArrayClass()) {
- return IsAssignableFromArray(src);
- } else {
- return !src->IsInterface() && src->IsSubClass(this);
- }
- }
-
- Class* GetSuperClass() const {
- // Can only get super class for loaded classes (hack for when runtime is
- // initializing)
- DCHECK(IsLoaded() || !Runtime::Current()->IsStarted()) << IsLoaded();
- return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Class, super_class_), false);
- }
-
- void SetSuperClass(Class *new_super_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- // super class is assigned once, except during class linker initialization
- Class* old_super_class = GetFieldObject<Class*>(
- OFFSET_OF_OBJECT_MEMBER(Class, super_class_), false);
- DCHECK(old_super_class == NULL || old_super_class == new_super_class);
- DCHECK(new_super_class != NULL);
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, super_class_), new_super_class, false);
- }
-
- bool HasSuperClass() const {
- return GetSuperClass() != NULL;
- }
-
- static MemberOffset SuperClassOffset() {
- return MemberOffset(OFFSETOF_MEMBER(Class, super_class_));
- }
-
- ClassLoader* GetClassLoader() const;
-
- void SetClassLoader(ClassLoader* new_cl) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static MemberOffset DexCacheOffset() {
- return MemberOffset(OFFSETOF_MEMBER(Class, dex_cache_));
- }
-
- enum {
- kDumpClassFullDetail = 1,
- kDumpClassClassLoader = (1 << 1),
- kDumpClassInitialized = (1 << 2),
- };
-
- void DumpClass(std::ostream& os, int flags) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- DexCache* GetDexCache() const;
-
- void SetDexCache(DexCache* new_dex_cache) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- ObjectArray<AbstractMethod>* GetDirectMethods() const {
- DCHECK(IsLoaded() || IsErroneous());
- return GetFieldObject<ObjectArray<AbstractMethod>*>(
- OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), false);
- }
-
- void SetDirectMethods(ObjectArray<AbstractMethod>* new_direct_methods)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(NULL == GetFieldObject<ObjectArray<AbstractMethod>*>(
- OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), false));
- DCHECK_NE(0, new_direct_methods->GetLength());
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_),
- new_direct_methods, false);
- }
-
- AbstractMethod* GetDirectMethod(int32_t i) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetDirectMethods()->Get(i);
- }
-
- void SetDirectMethod(uint32_t i, AbstractMethod* f) // TODO: uint16_t
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){
- ObjectArray<AbstractMethod>* direct_methods =
- GetFieldObject<ObjectArray<AbstractMethod>*>(
- OFFSET_OF_OBJECT_MEMBER(Class, direct_methods_), false);
- direct_methods->Set(i, f);
- }
-
- // Returns the number of static, private, and constructor methods.
- size_t NumDirectMethods() const {
- return (GetDirectMethods() != NULL) ? GetDirectMethods()->GetLength() : 0;
- }
-
- ObjectArray<AbstractMethod>* GetVirtualMethods() const {
- DCHECK(IsLoaded() || IsErroneous());
- return GetFieldObject<ObjectArray<AbstractMethod>*>(
- OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_), false);
- }
-
- void SetVirtualMethods(ObjectArray<AbstractMethod>* new_virtual_methods)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- // TODO: we reassign virtual methods to grow the table for miranda
- // methods.. they should really just be assigned once
- DCHECK_NE(0, new_virtual_methods->GetLength());
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_),
- new_virtual_methods, false);
- }
-
- // Returns the number of non-inherited virtual methods.
- size_t NumVirtualMethods() const {
- return (GetVirtualMethods() != NULL) ? GetVirtualMethods()->GetLength() : 0;
- }
-
- AbstractMethod* GetVirtualMethod(uint32_t i) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(IsResolved() || IsErroneous());
- return GetVirtualMethods()->Get(i);
- }
-
- AbstractMethod* GetVirtualMethodDuringLinking(uint32_t i) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(IsLoaded() || IsErroneous());
- return GetVirtualMethods()->Get(i);
- }
-
- void SetVirtualMethod(uint32_t i, AbstractMethod* f) // TODO: uint16_t
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectArray<AbstractMethod>* virtual_methods =
- GetFieldObject<ObjectArray<AbstractMethod>*>(
- OFFSET_OF_OBJECT_MEMBER(Class, virtual_methods_), false);
- virtual_methods->Set(i, f);
- }
-
- ObjectArray<AbstractMethod>* GetVTable() const {
- DCHECK(IsResolved() || IsErroneous());
- return GetFieldObject<ObjectArray<AbstractMethod>*>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), false);
- }
-
- ObjectArray<AbstractMethod>* GetVTableDuringLinking() const {
- DCHECK(IsLoaded() || IsErroneous());
- return GetFieldObject<ObjectArray<AbstractMethod>*>(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), false);
- }
-
- void SetVTable(ObjectArray<AbstractMethod>* new_vtable)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, vtable_), new_vtable, false);
- }
-
- static MemberOffset VTableOffset() {
- return OFFSET_OF_OBJECT_MEMBER(Class, vtable_);
- }
-
- // Given a method implemented by this class but potentially from a
- // super class, return the specific implementation
- // method for this class.
- AbstractMethod* FindVirtualMethodForVirtual(AbstractMethod* method)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(!method->GetDeclaringClass()->IsInterface());
- // The argument method may from a super class.
- // Use the index to a potentially overridden one for this instance's class.
- return GetVTable()->Get(method->GetMethodIndex());
- }
-
- // Given a method implemented by this class' super class, return the specific implementation
- // method for this class.
- AbstractMethod* FindVirtualMethodForSuper(AbstractMethod* method)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(!method->GetDeclaringClass()->IsInterface());
- return GetSuperClass()->GetVTable()->Get(method->GetMethodIndex());
- }
-
- // Given a method implemented by this class, but potentially from a
- // super class or interface, return the specific implementation
- // method for this class.
- AbstractMethod* FindVirtualMethodForInterface(AbstractMethod* method)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- AbstractMethod* FindInterfaceMethod(const StringPiece& name, const StringPiece& descriptor) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- AbstractMethod* FindInterfaceMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- AbstractMethod* FindVirtualMethodForVirtualOrInterface(AbstractMethod* method)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (method->IsDirect()) {
- return method;
- }
- if (method->GetDeclaringClass()->IsInterface()) {
- return FindVirtualMethodForInterface(method);
- }
- return FindVirtualMethodForVirtual(method);
- }
-
- AbstractMethod* FindDeclaredVirtualMethod(const StringPiece& name, const StringPiece& signature) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- AbstractMethod* FindDeclaredVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- AbstractMethod* FindVirtualMethod(const StringPiece& name, const StringPiece& descriptor) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- AbstractMethod* FindVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- AbstractMethod* FindDeclaredDirectMethod(const StringPiece& name, const StringPiece& signature) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- AbstractMethod* FindDeclaredDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- AbstractMethod* FindDirectMethod(const StringPiece& name, const StringPiece& signature) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- AbstractMethod* FindDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- int32_t GetIfTableCount() const {
- IfTable* iftable = GetIfTable();
- if (iftable == NULL) {
- return 0;
- }
- return iftable->Count();
- }
-
- IfTable* GetIfTable() const {
- return GetFieldObject<IfTable*>(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), false);
- }
-
- void SetIfTable(IfTable* new_iftable)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, iftable_), new_iftable, false);
- }
-
- // Get instance fields of the class (See also GetSFields).
- ObjectArray<Field>* GetIFields() const {
- DCHECK(IsLoaded() || IsErroneous());
- return GetFieldObject<ObjectArray<Field>*>(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), false);
- }
-
- void SetIFields(ObjectArray<Field>* new_ifields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(NULL == GetFieldObject<ObjectArray<Field>*>(
- OFFSET_OF_OBJECT_MEMBER(Class, ifields_), false));
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, ifields_), new_ifields, false);
- }
-
- size_t NumInstanceFields() const {
- return (GetIFields() != NULL) ? GetIFields()->GetLength() : 0;
- }
-
- Field* GetInstanceField(uint32_t i) const // TODO: uint16_t
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){
- DCHECK_NE(NumInstanceFields(), 0U);
- return GetIFields()->Get(i);
- }
-
- void SetInstanceField(uint32_t i, Field* f) // TODO: uint16_t
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){
- ObjectArray<Field>* ifields= GetFieldObject<ObjectArray<Field>*>(
- OFFSET_OF_OBJECT_MEMBER(Class, ifields_), false);
- ifields->Set(i, f);
- }
-
- // Returns the number of instance fields containing reference types.
- size_t NumReferenceInstanceFields() const {
- DCHECK(IsResolved() || IsErroneous());
- DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_instance_fields_), false);
- }
-
- size_t NumReferenceInstanceFieldsDuringLinking() const {
- DCHECK(IsLoaded() || IsErroneous());
- DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_instance_fields_), false);
- }
-
- void SetNumReferenceInstanceFields(size_t new_num) {
- DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
- SetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_instance_fields_), new_num, false);
- }
-
- uint32_t GetReferenceInstanceOffsets() const {
- DCHECK(IsResolved() || IsErroneous());
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_instance_offsets_), false);
- }
-
- void SetReferenceInstanceOffsets(uint32_t new_reference_offsets);
-
- // Beginning of static field data
- static MemberOffset FieldsOffset() {
- return OFFSET_OF_OBJECT_MEMBER(Class, fields_);
- }
-
- // Returns the number of static fields containing reference types.
- size_t NumReferenceStaticFields() const {
- DCHECK(IsResolved() || IsErroneous());
- DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_static_fields_), false);
- }
-
- size_t NumReferenceStaticFieldsDuringLinking() const {
- DCHECK(IsLoaded() || IsErroneous());
- DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_static_fields_), false);
- }
-
- void SetNumReferenceStaticFields(size_t new_num) {
- DCHECK_EQ(sizeof(size_t), sizeof(int32_t));
- SetField32(OFFSET_OF_OBJECT_MEMBER(Class, num_reference_static_fields_), new_num, false);
- }
-
- // Gets the static fields of the class.
- ObjectArray<Field>* GetSFields() const {
- DCHECK(IsLoaded() || IsErroneous());
- return GetFieldObject<ObjectArray<Field>*>(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), false);
- }
-
- void SetSFields(ObjectArray<Field>* new_sfields) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(NULL == GetFieldObject<ObjectArray<Field>*>(
- OFFSET_OF_OBJECT_MEMBER(Class, sfields_), false));
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, sfields_), new_sfields, false);
- }
-
- size_t NumStaticFields() const {
- return (GetSFields() != NULL) ? GetSFields()->GetLength() : 0;
- }
-
- Field* GetStaticField(uint32_t i) const // TODO: uint16_t
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return GetSFields()->Get(i);
- }
-
- void SetStaticField(uint32_t i, Field* f) // TODO: uint16_t
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ObjectArray<Field>* sfields= GetFieldObject<ObjectArray<Field>*>(
- OFFSET_OF_OBJECT_MEMBER(Class, sfields_), false);
- sfields->Set(i, f);
- }
-
- uint32_t GetReferenceStaticOffsets() const {
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, reference_static_offsets_), false);
- }
-
- void SetReferenceStaticOffsets(uint32_t new_reference_offsets);
-
- // Find a static or instance field using the JLS resolution order
- Field* FindField(const StringPiece& name, const StringPiece& type)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Finds the given instance field in this class or a superclass.
- Field* FindInstanceField(const StringPiece& name, const StringPiece& type)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Finds the given instance field in this class or a superclass, only searches classes that
- // have the same dex cache.
- Field* FindInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- Field* FindDeclaredInstanceField(const StringPiece& name, const StringPiece& type)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- Field* FindDeclaredInstanceField(const DexCache* dex_cache, uint32_t dex_field_idx)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Finds the given static field in this class or a superclass.
- Field* FindStaticField(const StringPiece& name, const StringPiece& type)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Finds the given static field in this class or superclass, only searches classes that
- // have the same dex cache.
- Field* FindStaticField(const DexCache* dex_cache, uint32_t dex_field_idx)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- Field* FindDeclaredStaticField(const StringPiece& name, const StringPiece& type)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- Field* FindDeclaredStaticField(const DexCache* dex_cache, uint32_t dex_field_idx)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- pid_t GetClinitThreadId() const {
- DCHECK(IsIdxLoaded() || IsErroneous());
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), false);
- }
-
- void SetClinitThreadId(pid_t new_clinit_thread_id) {
- SetField32(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_), new_clinit_thread_id, false);
- }
-
- Class* GetVerifyErrorClass() const {
- // DCHECK(IsErroneous());
- return GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), false);
- }
-
- uint16_t GetDexTypeIndex() const {
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_), false);
- }
-
- void SetDexTypeIndex(uint16_t type_idx) {
- SetField32(OFFSET_OF_OBJECT_MEMBER(Class, dex_type_idx_), type_idx, false);
- }
-
- static Class* GetJavaLangClass() {
- DCHECK(java_lang_Class_ != NULL);
- return java_lang_Class_;
- }
-
- // Can't call this SetClass or else gets called instead of Object::SetClass in places.
- static void SetClassClass(Class* java_lang_Class);
- static void ResetClass();
-
- private:
- void SetVerifyErrorClass(Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- CHECK(klass != NULL) << PrettyClass(this);
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), klass, false);
- }
-
- bool Implements(const Class* klass) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool IsArrayAssignableFromArray(const Class* klass) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool IsAssignableFromArray(const Class* klass) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // defining class loader, or NULL for the "bootstrap" system loader
- ClassLoader* class_loader_;
-
- // For array classes, the component class object for instanceof/checkcast
- // (for String[][][], this will be String[][]). NULL for non-array classes.
- Class* component_type_;
-
- // DexCache of resolved constant pool entries (will be NULL for classes generated by the
- // runtime such as arrays and primitive classes).
- DexCache* dex_cache_;
-
- // static, private, and <init> methods
- ObjectArray<AbstractMethod>* direct_methods_;
-
- // instance fields
- //
- // These describe the layout of the contents of an Object.
- // Note that only the fields directly declared by this class are
- // listed in ifields; fields declared by a superclass are listed in
- // the superclass's Class.ifields.
- //
- // All instance fields that refer to objects are guaranteed to be at
- // the beginning of the field list. num_reference_instance_fields_
- // specifies the number of reference fields.
- ObjectArray<Field>* ifields_;
-
- // The interface table (iftable_) contains pairs of a interface class and an array of the
- // interface methods. There is one pair per interface supported by this class. That means one
- // pair for each interface we support directly, indirectly via superclass, or indirectly via a
- // superinterface. This will be null if neither we nor our superclass implement any interfaces.
- //
- // Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()".
- // Invoke faceObj.blah(), where "blah" is part of the Face interface. We can't easily use a
- // single vtable.
- //
- // For every interface a concrete class implements, we create an array of the concrete vtable_
- // methods for the methods in the interface.
- IfTable* iftable_;
-
- // descriptor for the class such as "java.lang.Class" or "[C". Lazily initialized by ComputeName
- String* name_;
-
- // Static fields
- ObjectArray<Field>* sfields_;
-
- // The superclass, or NULL if this is java.lang.Object, an interface or primitive type.
- Class* super_class_;
-
- // If class verify fails, we must return same error on subsequent tries.
- Class* verify_error_class_;
-
- // virtual methods defined in this class; invoked through vtable
- ObjectArray<AbstractMethod>* virtual_methods_;
-
- // Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass is
- // copied in, and virtual methods from our class either replace those from the super or are
- // appended. For abstract classes, methods may be created in the vtable that aren't in
- // virtual_ methods_ for miranda methods.
- ObjectArray<AbstractMethod>* vtable_;
-
- // access flags; low 16 bits are defined by VM spec
- uint32_t access_flags_;
-
- // Total size of the Class instance; used when allocating storage on gc heap.
- // See also object_size_.
- size_t class_size_;
-
- // tid used to check for recursive <clinit> invocation
- pid_t clinit_thread_id_;
-
- // type index from dex file
- // TODO: really 16bits
- uint32_t dex_type_idx_;
-
- // number of instance fields that are object refs
- size_t num_reference_instance_fields_;
-
- // number of static fields that are object refs
- size_t num_reference_static_fields_;
-
- // Total object size; used when allocating storage on gc heap.
- // (For interfaces and abstract classes this will be zero.)
- // See also class_size_.
- size_t object_size_;
-
- // primitive type value, or Primitive::kPrimNot (0); set for generated prim classes
- Primitive::Type primitive_type_;
-
- // Bitmap of offsets of ifields.
- uint32_t reference_instance_offsets_;
-
- // Bitmap of offsets of sfields.
- uint32_t reference_static_offsets_;
-
- // state of class initialization
- Status status_;
-
- // TODO: ?
- // initiating class loader list
- // NOTE: for classes with low serialNumber, these are unused, and the
- // values are kept in a table in gDvm.
- // InitiatingLoaderList initiating_loader_list_;
-
- // Location of first static field.
- uint32_t fields_[0];
-
- // java.lang.Class
- static Class* java_lang_Class_;
-
- friend struct ClassOffsets; // for verifying offset information
- DISALLOW_IMPLICIT_CONSTRUCTORS(Class);
-};
-
-std::ostream& operator<<(std::ostream& os, const Class::Status& rhs);
-
-inline void Object::SetClass(Class* new_klass) {
- // new_klass may be NULL prior to class linker initialization
- // We don't mark the card since the class is guaranteed to be referenced from another location.
- // Proxy classes are held live by the class loader, and other classes are roots of the class
- // linker.
- SetFieldPtr(OFFSET_OF_OBJECT_MEMBER(Object, klass_), new_klass, false, false);
-}
-
-inline bool Object::InstanceOf(const Class* klass) const {
- DCHECK(klass != NULL);
- DCHECK(GetClass() != NULL);
- return klass->IsAssignableFrom(GetClass());
-}
-
-inline bool Object::IsClass() const {
- Class* java_lang_Class = GetClass()->GetClass();
- return GetClass() == java_lang_Class;
-}
-
-inline bool Object::IsObjectArray() const {
- return IsArrayInstance() && !GetClass()->GetComponentType()->IsPrimitive();
-}
-
-template<class T>
-inline ObjectArray<T>* Object::AsObjectArray() {
- DCHECK(IsObjectArray());
- return down_cast<ObjectArray<T>*>(this);
-}
-
-template<class T>
-inline const ObjectArray<T>* Object::AsObjectArray() const {
- DCHECK(IsObjectArray());
- return down_cast<const ObjectArray<T>*>(this);
-}
-
-inline bool Object::IsArrayInstance() const {
- return GetClass()->IsArrayClass();
-}
-
-inline bool Object::IsField() const {
- return GetClass()->IsFieldClass();
-}
-
-inline bool Object::IsMethod() const {
- return GetClass()->IsMethodClass();
-}
-
-inline bool Object::IsReferenceInstance() const {
- return GetClass()->IsReferenceClass();
-}
-
-inline bool Object::IsWeakReferenceInstance() const {
- return GetClass()->IsWeakReferenceClass();
-}
-
-inline bool Object::IsSoftReferenceInstance() const {
- return GetClass()->IsSoftReferenceClass();
-}
-
-inline bool Object::IsFinalizerReferenceInstance() const {
- return GetClass()->IsFinalizerReferenceClass();
-}
-
-inline bool Object::IsPhantomReferenceInstance() const {
- return GetClass()->IsPhantomReferenceClass();
-}
-
-inline size_t Object::SizeOf() const {
- size_t result;
- if (IsArrayInstance()) {
- result = AsArray()->SizeOf();
- } else if (IsClass()) {
- result = AsClass()->SizeOf();
- } else {
- result = GetClass()->GetObjectSize();
- }
- DCHECK(!IsField() || result == sizeof(Field));
- DCHECK(!IsMethod() || result == sizeof(AbstractMethod));
- return result;
-}
-
-inline Class* Field::GetDeclaringClass() const {
- Class* result = GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(Field, declaring_class_), false);
- DCHECK(result != NULL);
- DCHECK(result->IsLoaded() || result->IsErroneous());
- return result;
-}
-
-inline void Field::SetDeclaringClass(Class *new_declaring_class) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Field, declaring_class_), new_declaring_class, false);
-}
-
-inline Class* AbstractMethod::GetDeclaringClass() const {
- Class* result = GetFieldObject<Class*>(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, declaring_class_), false);
- DCHECK(result != NULL) << this;
- DCHECK(result->IsIdxLoaded() || result->IsErroneous()) << this;
- return result;
-}
-
-inline void AbstractMethod::SetDeclaringClass(Class *new_declaring_class) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, declaring_class_), new_declaring_class, false);
-}
-
-inline size_t Array::SizeOf() const {
- // This is safe from overflow because the array was already allocated, so we know it's sane.
- size_t component_size = GetClass()->GetComponentSize();
- int32_t component_count = GetLength();
- size_t header_size = sizeof(Object) + (component_size == sizeof(int64_t) ? 8 : 4);
- size_t data_size = component_count * component_size;
- return header_size + data_size;
-}
-
-template<class T>
-void ObjectArray<T>::Set(int32_t i, T* object) {
- if (LIKELY(IsValidIndex(i))) {
- if (object != NULL) {
- Class* element_class = GetClass()->GetComponentType();
- if (UNLIKELY(!object->InstanceOf(element_class))) {
- ThrowArrayStoreException(object);
- return;
- }
- }
- MemberOffset data_offset(DataOffset(sizeof(Object*)).Int32Value() + i * sizeof(Object*));
- SetFieldObject(data_offset, object, false);
- }
-}
-
-template<class T>
-void ObjectArray<T>::SetWithoutChecks(int32_t i, T* object) {
- DCHECK(IsValidIndex(i));
- MemberOffset data_offset(DataOffset(sizeof(Object*)).Int32Value() + i * sizeof(Object*));
- SetFieldObject(data_offset, object, false);
-}
-
-template<class T>
-void ObjectArray<T>::SetPtrWithoutChecks(int32_t i, T* object) {
- DCHECK(IsValidIndex(i));
- MemberOffset data_offset(DataOffset(sizeof(Object*)).Int32Value() + i * sizeof(Object*));
- SetFieldPtr(data_offset, object, false);
-}
-
-template<class T>
-T* ObjectArray<T>::GetWithoutChecks(int32_t i) const {
- DCHECK(IsValidIndex(i));
- MemberOffset data_offset(DataOffset(sizeof(Object*)).Int32Value() + i * sizeof(Object*));
- return GetFieldObject<T*>(data_offset, false);
-}
-
-template<class T>
-void ObjectArray<T>::Copy(const ObjectArray<T>* src, int src_pos,
- ObjectArray<T>* dst, int dst_pos,
- size_t length) {
- if (src->IsValidIndex(src_pos) &&
- src->IsValidIndex(src_pos+length-1) &&
- dst->IsValidIndex(dst_pos) &&
- dst->IsValidIndex(dst_pos+length-1)) {
- MemberOffset src_offset(DataOffset(sizeof(Object*)).Int32Value() + src_pos * sizeof(Object*));
- MemberOffset dst_offset(DataOffset(sizeof(Object*)).Int32Value() + dst_pos * sizeof(Object*));
- Class* array_class = dst->GetClass();
- Heap* heap = Runtime::Current()->GetHeap();
- if (array_class == src->GetClass()) {
- // No need for array store checks if arrays are of the same type
- for (size_t i = 0; i < length; i++) {
- Object* object = src->GetFieldObject<Object*>(src_offset, false);
- heap->VerifyObject(object);
- // directly set field, we do a bulk write barrier at the end
- dst->SetField32(dst_offset, reinterpret_cast<uint32_t>(object), false, true);
- src_offset = MemberOffset(src_offset.Uint32Value() + sizeof(Object*));
- dst_offset = MemberOffset(dst_offset.Uint32Value() + sizeof(Object*));
- }
- } else {
- Class* element_class = array_class->GetComponentType();
- CHECK(!element_class->IsPrimitive());
- for (size_t i = 0; i < length; i++) {
- Object* object = src->GetFieldObject<Object*>(src_offset, false);
- if (object != NULL && !object->InstanceOf(element_class)) {
- dst->ThrowArrayStoreException(object);
- return;
- }
- heap->VerifyObject(object);
- // directly set field, we do a bulk write barrier at the end
- dst->SetField32(dst_offset, reinterpret_cast<uint32_t>(object), false, true);
- src_offset = MemberOffset(src_offset.Uint32Value() + sizeof(Object*));
- dst_offset = MemberOffset(dst_offset.Uint32Value() + sizeof(Object*));
- }
- }
- heap->WriteBarrierArray(dst, dst_pos, length);
- }
-}
-
-inline void IfTable::SetInterface(int32_t i, Class* interface) {
- DCHECK(interface != NULL);
- DCHECK(interface->IsInterface());
- DCHECK(Get((i * kMax) + kInterface) == NULL);
- Set((i * kMax) + kInterface, interface);
-}
-
-class MANAGED ClassClass : public Class {
- private:
- int32_t padding_;
- int64_t serialVersionUID_;
- friend struct ClassClassOffsets; // for verifying offset information
- DISALLOW_IMPLICIT_CONSTRUCTORS(ClassClass);
-};
-
-class MANAGED StringClass : public Class {
- private:
- CharArray* ASCII_;
- Object* CASE_INSENSITIVE_ORDER_;
- uint32_t REPLACEMENT_CHAR_;
- int64_t serialVersionUID_;
- friend struct StringClassOffsets; // for verifying offset information
- DISALLOW_IMPLICIT_CONSTRUCTORS(StringClass);
-};
-
-class MANAGED FieldClass : public Class {
- private:
- Object* ORDER_BY_NAME_AND_DECLARING_CLASS_;
- friend struct FieldClassOffsets; // for verifying offset information
- DISALLOW_IMPLICIT_CONSTRUCTORS(FieldClass);
-};
-
-class MANAGED MethodClass : public Class {
- private:
- Object* ORDER_BY_SIGNATURE_;
- friend struct MethodClassOffsets; // for verifying offset information
- DISALLOW_IMPLICIT_CONSTRUCTORS(MethodClass);
-};
-
-template<class T>
-class MANAGED PrimitiveArray : public Array {
- public:
- typedef T ElementType;
-
- static PrimitiveArray<T>* Alloc(Thread* self, size_t length)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- const T* GetData() const {
- intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(sizeof(T)).Int32Value();
- return reinterpret_cast<T*>(data);
- }
-
- T* GetData() {
- intptr_t data = reinterpret_cast<intptr_t>(this) + DataOffset(sizeof(T)).Int32Value();
- return reinterpret_cast<T*>(data);
- }
-
- T Get(int32_t i) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (!IsValidIndex(i)) {
- return T(0);
- }
- return GetData()[i];
- }
-
- void Set(int32_t i, T value) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (IsValidIndex(i)) {
- GetData()[i] = value;
- }
- }
-
- static void SetArrayClass(Class* array_class) {
- CHECK(array_class_ == NULL);
- CHECK(array_class != NULL);
- array_class_ = array_class;
- }
-
- static void ResetArrayClass() {
- CHECK(array_class_ != NULL);
- array_class_ = NULL;
- }
-
- private:
- static Class* array_class_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(PrimitiveArray);
-};
-
-// C++ mirror of java.lang.String
-class MANAGED String : public Object {
- public:
- static MemberOffset CountOffset() {
- return OFFSET_OF_OBJECT_MEMBER(String, count_);
- }
-
- static MemberOffset ValueOffset() {
- return OFFSET_OF_OBJECT_MEMBER(String, array_);
- }
-
- static MemberOffset OffsetOffset() {
- return OFFSET_OF_OBJECT_MEMBER(String, offset_);
- }
-
- const CharArray* GetCharArray() const {
- return GetFieldObject<const CharArray*>(ValueOffset(), false);
- }
-
- int32_t GetOffset() const {
- int32_t result = GetField32(OffsetOffset(), false);
- DCHECK_LE(0, result);
- return result;
- }
-
- int32_t GetLength() const;
-
- int32_t GetHashCode() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- void ComputeHashCode() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- SetHashCode(ComputeUtf16Hash(GetCharArray(), GetOffset(), GetLength()));
- }
-
- int32_t GetUtfLength() const {
- return CountUtf8Bytes(GetCharArray()->GetData() + GetOffset(), GetLength());
- }
-
- uint16_t CharAt(int32_t index) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- String* Intern() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- 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(Thread* self, const char* utf)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static String* AllocFromModifiedUtf8(Thread* self, int32_t utf16_length,
- const char* utf8_data_in)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static String* Alloc(Thread* self, Class* java_lang_String, int32_t utf16_length)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static String* Alloc(Thread* self, Class* java_lang_String, CharArray* array)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- bool Equals(const char* modified_utf8) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // TODO: do we need this overload? give it a more intention-revealing name.
- bool Equals(const StringPiece& modified_utf8) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- bool Equals(const String* that) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Compare UTF-16 code point values not in a locale-sensitive manner
- int Compare(int32_t utf16_length, const char* utf8_data_in);
-
- // TODO: do we need this overload? give it a more intention-revealing name.
- bool Equals(const uint16_t* that_chars, int32_t that_offset,
- int32_t that_length) const
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // Create a modified UTF-8 encoded std::string from a java/lang/String object.
- std::string ToModifiedUtf8() const;
-
- int32_t FastIndexOf(int32_t ch, int32_t start) {
- int32_t count = GetLength();
- if (start < 0) {
- start = 0;
- } else if (start > count) {
- start = count;
- }
- const uint16_t* chars = GetCharArray()->GetData() + GetOffset();
- const uint16_t* p = chars + start;
- const uint16_t* end = chars + count;
- while (p < end) {
- if (*p++ == ch) {
- return (p - 1) - chars;
- }
- }
- return -1;
- }
-
- int32_t CompareTo(String* other) const;
-
- static Class* GetJavaLangString() {
- DCHECK(java_lang_String_ != NULL);
- return java_lang_String_;
- }
-
- static void SetClass(Class* java_lang_String);
- static void ResetClass();
-
- private:
- void SetHashCode(int32_t new_hash_code) {
- DCHECK_EQ(0u,
- GetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_), false));
- SetField32(OFFSET_OF_OBJECT_MEMBER(String, hash_code_),
- new_hash_code, false);
- }
-
- void SetCount(int32_t new_count) {
- DCHECK_LE(0, new_count);
- SetField32(OFFSET_OF_OBJECT_MEMBER(String, count_), new_count, false);
- }
-
- void SetOffset(int32_t new_offset) {
- DCHECK_LE(0, new_offset);
- DCHECK_GE(GetLength(), new_offset);
- SetField32(OFFSET_OF_OBJECT_MEMBER(String, offset_), new_offset, false);
- }
-
- void SetArray(CharArray* new_array) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(new_array != NULL);
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(String, array_), new_array, false);
- }
-
- // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
- CharArray* array_;
-
- int32_t count_;
-
- uint32_t hash_code_;
-
- int32_t offset_;
-
- static Class* java_lang_String_;
-
- friend struct StringOffsets; // for verifying offset information
- FRIEND_TEST(ObjectTest, StringLength); // for SetOffset and SetCount
- DISALLOW_IMPLICIT_CONSTRUCTORS(String);
-};
-
-// TODO: remove? only used in a unit test of itself.
-struct StringHashCode {
- int32_t operator()(String* string) const {
- return string->GetHashCode();
- }
-};
-
-inline uint32_t Field::GetAccessFlags() const {
- DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Field, access_flags_), false);
-}
-
-inline MemberOffset Field::GetOffset() const {
- DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous());
- return MemberOffset(GetField32(OFFSET_OF_OBJECT_MEMBER(Field, offset_), false));
-}
-
-inline MemberOffset Field::GetOffsetDuringLinking() const {
- DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
- return MemberOffset(GetField32(OFFSET_OF_OBJECT_MEMBER(Field, offset_), false));
-}
-
-inline uint32_t Class::GetAccessFlags() const {
- // Check class is loaded or this is java.lang.String that has a
- // circularity issue during loading the names of its members
- DCHECK(IsLoaded() || IsErroneous() ||
- this == String::GetJavaLangString() ||
- this == Field::GetJavaLangReflectField() ||
- this == AbstractMethod::GetConstructorClass() ||
- this == AbstractMethod::GetMethodClass());
- return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, access_flags_), false);
-}
-
-inline uint32_t AbstractMethod::GetAccessFlags() const {
- DCHECK(GetDeclaringClass()->IsIdxLoaded() || GetDeclaringClass()->IsErroneous());
- return GetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, access_flags_), false);
-}
-
-inline uint16_t AbstractMethod::GetMethodIndex() const {
- DCHECK(GetDeclaringClass()->IsResolved() || GetDeclaringClass()->IsErroneous());
- return GetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, method_index_), false);
-}
-
-inline uint32_t AbstractMethod::GetDexMethodIndex() const {
- DCHECK(GetDeclaringClass()->IsLoaded() || GetDeclaringClass()->IsErroneous());
- return GetField32(OFFSET_OF_OBJECT_MEMBER(AbstractMethod, method_dex_index_), false);
-}
-
-inline bool AbstractMethod::CheckIncompatibleClassChange(InvokeType type) {
- switch (type) {
- case kStatic:
- return !IsStatic();
- case kDirect:
- return !IsDirect() || IsStatic();
- case kVirtual: {
- Class* methods_class = GetDeclaringClass();
- return IsDirect() || (methods_class->IsInterface() && !IsMiranda());
- }
- case kSuper:
- return false; // TODO: appropriate checks for call to super class.
- case kInterface: {
- Class* methods_class = GetDeclaringClass();
- return IsDirect() || !(methods_class->IsInterface() || methods_class->IsObjectClass());
- }
- default:
- LOG(FATAL) << "Unreachable - invocation type: " << type;
- return true;
- }
-}
-
-inline void AbstractMethod::AssertPcIsWithinCode(uintptr_t pc) const {
- if (!kIsDebugBuild) {
- return;
- }
- if (IsNative() || IsRuntimeMethod() || IsProxyMethod()) {
- return;
- }
- Runtime* runtime = Runtime::Current();
- if (GetCode() == runtime->GetResolutionStubArray(Runtime::kStaticMethod)->GetData()) {
- return;
- }
- DCHECK(IsWithinCode(pc))
- << PrettyMethod(this)
- << " pc=" << std::hex << pc
- << " code=" << GetCode()
- << " size=" << GetCodeSize();
-}
-
-inline String* Class::GetName() const {
- return GetFieldObject<String*>(OFFSET_OF_OBJECT_MEMBER(Class, name_), false);
-}
-inline void Class::SetName(String* name) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, name_), name, false);
-}
-
-// C++ mirror of java.lang.Throwable
-class MANAGED Throwable : public Object {
- public:
- void SetDetailMessage(String* new_detail_message) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Throwable, detail_message_), new_detail_message, false);
- }
- String* GetDetailMessage() const {
- return GetFieldObject<String*>(OFFSET_OF_OBJECT_MEMBER(Throwable, detail_message_), false);
- }
- std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- // This is a runtime version of initCause, you shouldn't use it if initCause may have been
- // overridden. Also it asserts rather than throwing exceptions. Currently this is only used
- // in cases like the verifier where the checks cannot fail and initCause isn't overridden.
- void SetCause(Throwable* cause) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool IsCheckedException() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static Class* GetJavaLangThrowable() {
- DCHECK(java_lang_Throwable_ != NULL);
- return java_lang_Throwable_;
- }
-
- static void SetClass(Class* java_lang_Throwable);
- static void ResetClass();
-
- private:
- Object* GetStackState() const {
- return GetFieldObject<Object*>(OFFSET_OF_OBJECT_MEMBER(Throwable, stack_state_), true);
- }
-
- // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
- Throwable* cause_;
- String* detail_message_;
- Object* stack_state_; // Note this is Java volatile:
- Object* stack_trace_;
- Object* suppressed_exceptions_;
-
- static Class* java_lang_Throwable_;
-
- friend struct ThrowableOffsets; // for verifying offset information
- DISALLOW_IMPLICIT_CONSTRUCTORS(Throwable);
-};
-
-// C++ mirror of java.lang.StackTraceElement
-class MANAGED StackTraceElement : public Object {
- public:
- const String* GetDeclaringClass() const {
- return GetFieldObject<const String*>(
- OFFSET_OF_OBJECT_MEMBER(StackTraceElement, declaring_class_), false);
- }
-
- const String* GetMethodName() const {
- return GetFieldObject<const String*>(
- OFFSET_OF_OBJECT_MEMBER(StackTraceElement, method_name_), false);
- }
-
- const String* GetFileName() const {
- return GetFieldObject<const String*>(
- OFFSET_OF_OBJECT_MEMBER(StackTraceElement, file_name_), false);
- }
-
- int32_t GetLineNumber() const {
- return GetField32(
- OFFSET_OF_OBJECT_MEMBER(StackTraceElement, line_number_), false);
- }
-
- static StackTraceElement* Alloc(Thread* self,
- String* declaring_class,
- String* method_name,
- String* file_name,
- int32_t line_number)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-
- static void SetClass(Class* java_lang_StackTraceElement);
-
- static void ResetClass();
-
- private:
- // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
- String* declaring_class_;
- String* file_name_;
- String* method_name_;
- int32_t line_number_;
-
- static Class* GetStackTraceElement() {
- DCHECK(java_lang_StackTraceElement_ != NULL);
- return java_lang_StackTraceElement_;
- }
-
- static Class* java_lang_StackTraceElement_;
-
- friend struct StackTraceElementOffsets; // for verifying offset information
- DISALLOW_IMPLICIT_CONSTRUCTORS(StackTraceElement);
-};
-
-class MANAGED SynthesizedProxyClass : public Class {
- public:
- ObjectArray<Class>* GetInterfaces() {
- return interfaces_;
- }
-
- ObjectArray<ObjectArray<Class> >* GetThrows() {
- return throws_;
- }
-
- private:
- ObjectArray<Class>* interfaces_;
- ObjectArray<ObjectArray<Class> >* throws_;
- DISALLOW_IMPLICIT_CONSTRUCTORS(SynthesizedProxyClass);
-};
-
-class MANAGED Proxy : public Object {
- private:
- Object* h_;
-
- friend struct ProxyOffsets; // for verifying offset information
- DISALLOW_IMPLICIT_CONSTRUCTORS(Proxy);
-};
-
-} // namespace art
-
-#endif // ART_SRC_OBJECT_H_
diff --git a/src/object_utils.h b/src/object_utils.h
index 068dd66..ea4de90 100644
--- a/src/object_utils.h
+++ b/src/object_utils.h
@@ -18,14 +18,17 @@
#define ART_SRC_OBJECT_UTILS_H_
#include "class_linker.h"
-#include "dex_cache.h"
#include "dex_file.h"
-#include "intern_table.h"
#include "monitor.h"
-#include "object.h"
+#include "mirror/abstract_method.h"
+#include "mirror/class.h"
+#include "mirror/dex_cache.h"
+#include "mirror/field.h"
+#include "mirror/iftable.h"
+#include "mirror/string.h"
+
#include "runtime.h"
#include "sirt_ref.h"
-#include "UniquePtr.h"
#include <string>
@@ -33,7 +36,7 @@
class ObjectLock {
public:
- explicit ObjectLock(Thread* self, Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
+ explicit ObjectLock(Thread* self, mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: self_(self), obj_(object) {
CHECK(object != NULL);
obj_->MonitorEnter(self_);
@@ -57,13 +60,13 @@
private:
Thread* const self_;
- Object* obj_;
+ mirror::Object* obj_;
DISALLOW_COPY_AND_ASSIGN(ObjectLock);
};
class ClassHelper {
public:
- ClassHelper(const Class* c = NULL, ClassLinker* l = NULL)
+ ClassHelper(const mirror::Class* c = NULL, ClassLinker* l = NULL)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: class_def_(NULL),
class_linker_(l),
@@ -76,12 +79,12 @@
}
}
- void ChangeClass(const Class* new_c)
+ void ChangeClass(const mirror::Class* new_c)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK(new_c != NULL) << "klass_=" << klass_; // Log what we were changing from if any
CHECK(new_c->IsClass()) << "new_c=" << new_c;
if (dex_cache_ != NULL) {
- DexCache* new_c_dex_cache = new_c->GetDexCache();
+ mirror::DexCache* new_c_dex_cache = new_c->GetDexCache();
if (new_c_dex_cache != dex_cache_) {
dex_cache_ = new_c_dex_cache;
dex_file_ = NULL;
@@ -112,7 +115,7 @@
const char* GetArrayDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::string result("[");
- const Class* saved_klass = klass_;
+ const mirror::Class* saved_klass = klass_;
CHECK(saved_klass != NULL);
ChangeClass(klass_->GetComponentType());
result += GetDescriptor();
@@ -157,7 +160,7 @@
return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_;
}
- Class* GetDirectInterface(uint32_t idx)
+ mirror::Class* GetDirectInterface(uint32_t idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(klass_ != NULL);
DCHECK(!klass_->IsPrimitive());
@@ -172,7 +175,7 @@
return klass_->GetIfTable()->GetInterface(idx);
} else {
uint16_t type_idx = GetDirectInterfaceTypeIdx(idx);
- Class* interface = GetDexCache()->GetResolvedType(type_idx);
+ mirror::Class* interface = GetDexCache()->GetResolvedType(type_idx);
if (interface == NULL) {
interface = GetClassLinker()->ResolveType(GetDexFile(), type_idx, klass_);
CHECK(interface != NULL || Thread::Current()->IsExceptionPending());
@@ -190,7 +193,7 @@
}
std::string GetLocation() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DexCache* dex_cache = GetDexCache();
+ mirror::DexCache* dex_cache = GetDexCache();
if (dex_cache != NULL && !klass_->IsProxyClass()) {
return dex_cache->GetLocation()->ToModifiedUtf8();
} else {
@@ -206,8 +209,8 @@
return *dex_file_;
}
- DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DexCache* result = dex_cache_;
+ mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ mirror::DexCache* result = dex_cache_;
if (result == NULL) {
DCHECK(klass_ != NULL);
result = klass_->GetDexCache();
@@ -241,10 +244,10 @@
const DexFile::ClassDef* class_def_;
ClassLinker* class_linker_;
- DexCache* dex_cache_;
+ mirror::DexCache* dex_cache_;
const DexFile* dex_file_;
const DexFile::TypeList* interface_type_list_;
- const Class* klass_;
+ const mirror::Class* klass_;
std::string descriptor_;
DISALLOW_COPY_AND_ASSIGN(ClassHelper);
@@ -253,14 +256,14 @@
class FieldHelper {
public:
FieldHelper() : class_linker_(NULL), dex_cache_(NULL), dex_file_(NULL), field_(NULL) {}
- explicit FieldHelper(const Field* f) : class_linker_(NULL), dex_cache_(NULL), dex_file_(NULL), field_(f) {}
- FieldHelper(const Field* f, ClassLinker* l)
+ explicit FieldHelper(const mirror::Field* f) : class_linker_(NULL), dex_cache_(NULL), dex_file_(NULL), field_(f) {}
+ FieldHelper(const mirror::Field* f, ClassLinker* l)
: class_linker_(l), dex_cache_(NULL), dex_file_(NULL), field_(f) {}
- void ChangeField(const Field* new_f) {
+ void ChangeField(const mirror::Field* new_f) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(new_f != NULL);
if (dex_cache_ != NULL) {
- DexCache* new_f_dex_cache = new_f->GetDeclaringClass()->GetDexCache();
+ mirror::DexCache* new_f_dex_cache = new_f->GetDeclaringClass()->GetDexCache();
if (new_f_dex_cache != dex_cache_) {
dex_cache_ = new_f_dex_cache;
dex_file_ = NULL;
@@ -279,22 +282,12 @@
return field_index == 0 ? "interfaces" : "throws";
}
}
- String* GetNameAsString() {
+ mirror::Class* GetType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
uint32_t field_index = field_->GetDexFieldIndex();
if (!field_->GetDeclaringClass()->IsProxyClass()) {
const DexFile& dex_file = GetDexFile();
const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
- return GetClassLinker()->ResolveString(dex_file, field_id.name_idx_, GetDexCache());
- } else {
- return Runtime::Current()->GetInternTable()->InternStrong(GetName());
- }
- }
- Class* GetType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- uint32_t field_index = field_->GetDexFieldIndex();
- if (!field_->GetDeclaringClass()->IsProxyClass()) {
- const DexFile& dex_file = GetDexFile();
- const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
- Class* type = GetDexCache()->GetResolvedType(field_id.type_idx_);
+ mirror::Class* type = GetDexCache()->GetResolvedType(field_id.type_idx_);
if (type == NULL) {
type = GetClassLinker()->ResolveType(field_id.type_idx_, field_);
CHECK(type != NULL || Thread::Current()->IsExceptionPending());
@@ -347,8 +340,8 @@
}
private:
- DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DexCache* result = dex_cache_;
+ mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ mirror::DexCache* result = dex_cache_;
if (result == NULL) {
result = field_->GetDeclaringClass()->GetDexCache();
dex_cache_ = result;
@@ -371,9 +364,9 @@
}
ClassLinker* class_linker_;
- DexCache* dex_cache_;
+ mirror::DexCache* dex_cache_;
const DexFile* dex_file_;
- const Field* field_;
+ const mirror::Field* field_;
std::string declaring_class_descriptor_;
DISALLOW_COPY_AND_ASSIGN(FieldHelper);
@@ -385,29 +378,29 @@
: class_linker_(NULL), dex_cache_(NULL), dex_file_(NULL), method_(NULL), shorty_(NULL),
shorty_len_(0) {}
- explicit MethodHelper(const AbstractMethod* m)
+ explicit MethodHelper(const mirror::AbstractMethod* m)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: class_linker_(NULL), dex_cache_(NULL), dex_file_(NULL), method_(NULL), shorty_(NULL),
shorty_len_(0) {
SetMethod(m);
}
- MethodHelper(const AbstractMethod* m, ClassLinker* l)
+ MethodHelper(const mirror::AbstractMethod* m, ClassLinker* l)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: class_linker_(l), dex_cache_(NULL), dex_file_(NULL), method_(NULL), shorty_(NULL),
shorty_len_(0) {
SetMethod(m);
}
- void ChangeMethod(AbstractMethod* new_m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ void ChangeMethod(mirror::AbstractMethod* new_m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK(new_m != NULL);
if (dex_cache_ != NULL) {
- Class* klass = new_m->GetDeclaringClass();
+ mirror::Class* klass = new_m->GetDeclaringClass();
if (klass->IsProxyClass()) {
dex_cache_ = NULL;
dex_file_ = NULL;
} else {
- DexCache* new_m_dex_cache = klass->GetDexCache();
+ mirror::DexCache* new_m_dex_cache = klass->GetDexCache();
if (new_m_dex_cache != dex_cache_) {
dex_cache_ = new_m_dex_cache;
dex_file_ = NULL;
@@ -439,7 +432,7 @@
}
}
- String* GetNameAsString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ mirror::String* GetNameAsString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile& dex_file = GetDexFile();
uint32_t dex_method_idx = method_->GetDexMethodIndex();
const DexFile::MethodId& method_id = dex_file.GetMethodId(dex_method_idx);
@@ -487,17 +480,18 @@
return GetDexFile().GetProtoParameters(proto);
}
- ObjectArray<Class>* GetParameterTypes(Thread* self)
+ mirror::ObjectArray<mirror::Class>* GetParameterTypes(Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile::TypeList* params = GetParameterTypeList();
uint32_t num_params = params == NULL ? 0 : params->Size();
- SirtRef<ObjectArray<Class> > result(self, GetClassLinker()->AllocClassArray(self, num_params));
+ SirtRef<mirror::ObjectArray<mirror::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_);
+ mirror::Class* param_type = GetClassFromTypeIdx(params->GetTypeItem(i).type_idx_);
if (param_type == NULL) {
DCHECK(Thread::Current()->IsExceptionPending());
return NULL;
@@ -507,7 +501,7 @@
return result.get();
}
- Class* GetReturnType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ mirror::Class* GetReturnType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile& dex_file = GetDexFile();
const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
@@ -536,7 +530,7 @@
const char* GetDeclaringClassDescriptor()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Class* klass = method_->GetDeclaringClass();
+ mirror::Class* klass = method_->GetDeclaringClass();
DCHECK(!klass->IsProxyClass());
uint16_t type_idx = klass->GetDexTypeIndex();
const DexFile& dex_file = GetDexFile();
@@ -561,7 +555,7 @@
return index;
}
- ClassLoader* GetClassLoader()
+ mirror::ClassLoader* GetClassLoader()
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return method_->GetDeclaringClass()->GetClassLoader();
}
@@ -626,9 +620,9 @@
return method_->GetDexCacheResolvedTypes()->Get(type_idx) != NULL;
}
- Class* GetClassFromTypeIdx(uint16_t type_idx)
+ mirror::Class* GetClassFromTypeIdx(uint16_t type_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Class* type = method_->GetDexCacheResolvedTypes()->Get(type_idx);
+ mirror::Class* type = method_->GetDexCacheResolvedTypes()->Get(type_idx);
if (type == NULL) {
type = GetClassLinker()->ResolveType(type_idx, method_);
CHECK(type != NULL || Thread::Current()->IsExceptionPending());
@@ -642,7 +636,7 @@
return dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx));
}
- Class* GetDexCacheResolvedType(uint16_t type_idx)
+ mirror::Class* GetDexCacheResolvedType(uint16_t type_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return method_->GetDexCacheResolvedTypes()->Get(type_idx);
}
@@ -650,24 +644,24 @@
const DexFile& GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile* result = dex_file_;
if (result == NULL) {
- const DexCache* dex_cache = GetDexCache();
+ const mirror::DexCache* dex_cache = GetDexCache();
result = dex_file_ = dex_cache->GetDexFile();
}
return *result;
}
- DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DexCache* result = dex_cache_;
+ mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ mirror::DexCache* result = dex_cache_;
if (result == NULL) {
- Class* klass = method_->GetDeclaringClass();
+ mirror::Class* klass = method_->GetDeclaringClass();
result = klass->GetDexCache();
dex_cache_ = result;
}
return result;
}
- String* ResolveString(uint32_t string_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- String* s = method_->GetDexCacheStrings()->Get(string_idx);
+ mirror::String* ResolveString(uint32_t string_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ mirror::String* s = method_->GetDexCacheStrings()->Get(string_idx);
if (UNLIKELY(s == NULL)) {
s = GetClassLinker()->ResolveString(GetDexFile(), string_idx, GetDexCache());
}
@@ -677,11 +671,11 @@
private:
// Set the method_ field, for proxy methods looking up the interface method via the resolved
// methods table.
- void SetMethod(const AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ void SetMethod(const mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (method != NULL) {
- Class* klass = method->GetDeclaringClass();
+ mirror::Class* klass = method->GetDeclaringClass();
if (klass->IsProxyClass()) {
- AbstractMethod* interface_method =
+ mirror::AbstractMethod* interface_method =
method->GetDexCacheResolvedMethods()->Get(method->GetDexMethodIndex());
CHECK(interface_method != NULL);
CHECK(interface_method == GetClassLinker()->FindMethodForProxy(klass, method));
@@ -701,9 +695,9 @@
}
ClassLinker* class_linker_;
- DexCache* dex_cache_;
+ mirror::DexCache* dex_cache_;
const DexFile* dex_file_;
- const AbstractMethod* method_;
+ const mirror::AbstractMethod* method_;
const char* shorty_;
uint32_t shorty_len_;
diff --git a/src/primitive.h b/src/primitive.h
index cb78ccc..eaa04cd 100644
--- a/src/primitive.h
+++ b/src/primitive.h
@@ -23,8 +23,9 @@
#include "base/macros.h"
namespace art {
-
+namespace mirror {
class Object;
+} // namespace mirror
class Primitive {
public:
@@ -77,7 +78,7 @@
case kPrimFloat: return 4;
case kPrimLong:
case kPrimDouble: return 8;
- case kPrimNot: return sizeof(Object*);
+ case kPrimNot: return sizeof(mirror::Object*);
default:
LOG(FATAL) << "Invalid type " << static_cast<int>(type);
return 0;
diff --git a/src/reference_table.cc b/src/reference_table.cc
index cdb3004..192535a 100644
--- a/src/reference_table.cc
+++ b/src/reference_table.cc
@@ -18,8 +18,14 @@
#include "base/mutex.h"
#include "indirect_reference_table.h"
-
-#include "object.h"
+#include "mirror/array.h"
+#include "mirror/array-inl.h"
+#include "mirror/class.h"
+#include "mirror/class-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/string.h"
+#include "thread.h"
+#include "utils.h"
namespace art {
@@ -32,7 +38,7 @@
ReferenceTable::~ReferenceTable() {
}
-void ReferenceTable::Add(const Object* obj) {
+void ReferenceTable::Add(const mirror::Object* obj) {
DCHECK(obj != NULL);
if (entries_.size() == max_size_) {
LOG(FATAL) << "ReferenceTable '" << name_ << "' "
@@ -41,7 +47,7 @@
entries_.push_back(obj);
}
-void ReferenceTable::Remove(const Object* obj) {
+void ReferenceTable::Remove(const mirror::Object* obj) {
// We iterate backwards on the assumption that references are LIFO.
for (int i = entries_.size() - 1; i >= 0; --i) {
if (entries_[i] == obj) {
@@ -53,7 +59,7 @@
// If "obj" is an array, return the number of elements in the array.
// Otherwise, return zero.
-static size_t GetElementCount(const Object* obj) {
+static size_t GetElementCount(const mirror::Object* obj) {
if (obj == NULL || obj == kClearedJniWeakGlobal || !obj->IsArrayInstance()) {
return 0;
}
@@ -61,7 +67,7 @@
}
struct ObjectComparator {
- bool operator()(const Object* obj1, const Object* obj2)
+ bool operator()(const mirror::Object* obj1, const mirror::Object* obj2)
// TODO: enable analysis when analysis can work with the STL.
NO_THREAD_SAFETY_ANALYSIS {
Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
@@ -99,7 +105,7 @@
// Pass in the number of elements in the array (or 0 if this is not an
// array object), and the number of additional objects that are identical
// or equivalent to the original.
-static void DumpSummaryLine(std::ostream& os, const Object* obj, size_t element_count,
+static void DumpSummaryLine(std::ostream& os, const mirror::Object* obj, size_t element_count,
int identical, int equiv)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (obj == NULL) {
@@ -153,7 +159,7 @@
}
os << " Last " << (count - first) << " entries (of " << count << "):\n";
for (int idx = count - 1; idx >= first; --idx) {
- const Object* ref = entries[idx];
+ const mirror::Object* ref = entries[idx];
if (ref == NULL) {
continue;
}
@@ -175,7 +181,7 @@
if (element_count != 0) {
StringAppendF(&extras, " (%zd elements)", element_count);
} else if (ref->GetClass()->IsStringClass()) {
- String* s = const_cast<Object*>(ref)->AsString();
+ mirror::String* s = const_cast<mirror::Object*>(ref)->AsString();
std::string utf8(s->ToModifiedUtf8());
if (s->GetLength() <= 16) {
StringAppendF(&extras, " \"%s\"", utf8.c_str());
@@ -206,8 +212,8 @@
size_t equiv = 0;
size_t identical = 0;
for (size_t idx = 1; idx < count; idx++) {
- const Object* prev = sorted_entries[idx-1];
- const Object* current = sorted_entries[idx];
+ const mirror::Object* prev = sorted_entries[idx-1];
+ const mirror::Object* current = sorted_entries[idx];
size_t element_count = GetElementCount(prev);
if (current == prev) {
// Same reference, added more than once.
@@ -225,7 +231,7 @@
DumpSummaryLine(os, sorted_entries.back(), GetElementCount(sorted_entries.back()), identical, equiv);
}
-void ReferenceTable::VisitRoots(Heap::RootVisitor* visitor, void* arg) {
+void ReferenceTable::VisitRoots(RootVisitor* visitor, void* arg) {
typedef Table::const_iterator It; // TODO: C++0x auto
for (It it = entries_.begin(), end = entries_.end(); it != end; ++it) {
visitor(*it, arg);
diff --git a/src/reference_table.h b/src/reference_table.h
index f398eb2..5abb5c7 100644
--- a/src/reference_table.h
+++ b/src/reference_table.h
@@ -22,11 +22,13 @@
#include <string>
#include <vector>
-#include "heap.h"
+#include "locks.h"
+#include "root_visitor.h"
namespace art {
-
+namespace mirror {
class Object;
+} // namespace mirror
// Maintain a table of references. Used for JNI monitor references and
// JNI pinned array references.
@@ -37,18 +39,18 @@
ReferenceTable(const char* name, size_t initial_size, size_t max_size);
~ReferenceTable();
- void Add(const Object* obj);
+ void Add(const mirror::Object* obj);
- void Remove(const Object* obj);
+ void Remove(const mirror::Object* obj);
size_t Size() const;
void Dump(std::ostream& os) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void VisitRoots(Heap::RootVisitor* visitor, void* arg);
+ void VisitRoots(RootVisitor* visitor, void* arg);
private:
- typedef std::vector<const Object*> Table;
+ typedef std::vector<const mirror::Object*> Table;
static void Dump(std::ostream& os, const Table& entries)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
friend class IndirectReferenceTable; // For Dump.
diff --git a/src/reference_table_test.cc b/src/reference_table_test.cc
index c400f83..16fbd94 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(soa.Self(), "hello");
+ mirror::Object* o1 = mirror::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(soa.Self(), 0);
+ mirror::Object* o2 = mirror::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 1ffad3f..16a5502 100644
--- a/src/reflection.cc
+++ b/src/reflection.cc
@@ -18,7 +18,13 @@
#include "class_linker.h"
#include "jni_internal.h"
-#include "object.h"
+#include "mirror/abstract_method.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/class.h"
+#include "mirror/class-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array.h"
+#include "mirror/object_array-inl.h"
#include "object_utils.h"
#include "scoped_thread_state_change.h"
#include "well_known_classes.h"
@@ -28,17 +34,17 @@
jobject InvokeMethod(const ScopedObjectAccess& soa, jobject javaMethod, jobject javaReceiver,
jobject javaArgs) {
jmethodID mid = soa.Env()->FromReflectedMethod(javaMethod);
- AbstractMethod* m = soa.DecodeMethod(mid);
+ mirror::AbstractMethod* m = soa.DecodeMethod(mid);
- Class* declaring_class = m->GetDeclaringClass();
+ mirror::Class* declaring_class = m->GetDeclaringClass();
if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(declaring_class, true, true)) {
return NULL;
}
- Object* receiver = NULL;
+ mirror::Object* receiver = NULL;
if (!m->IsStatic()) {
// Check that the receiver is non-null and an instance of the field's declaring class.
- receiver = soa.Decode<Object*>(javaReceiver);
+ receiver = soa.Decode<mirror::Object*>(javaReceiver);
if (!VerifyObjectInClass(receiver, declaring_class)) {
return NULL;
}
@@ -49,7 +55,8 @@
}
// Get our arrays of arguments and their types, and check they're the same size.
- ObjectArray<Object>* objects = soa.Decode<ObjectArray<Object>*>(javaArgs);
+ mirror::ObjectArray<mirror::Object>* objects =
+ soa.Decode<mirror::ObjectArray<mirror::Object>*>(javaArgs);
MethodHelper mh(m);
const DexFile::TypeList* classes = mh.GetParameterTypeList();
uint32_t classes_size = classes == NULL ? 0 : classes->Size();
@@ -65,8 +72,8 @@
UniquePtr<jvalue[]> args(new jvalue[arg_count]);
JValue* decoded_args = reinterpret_cast<JValue*>(args.get());
for (uint32_t i = 0; i < arg_count; ++i) {
- Object* arg = objects->Get(i);
- Class* dst_class = mh.GetClassFromTypeIdx(classes->GetTypeItem(i).type_idx_);
+ mirror::Object* arg = objects->Get(i);
+ mirror::Class* dst_class = mh.GetClassFromTypeIdx(classes->GetTypeItem(i).type_idx_);
if (!UnboxPrimitiveForArgument(arg, dst_class, decoded_args[i], m, i)) {
return NULL;
}
@@ -93,7 +100,7 @@
return soa.AddLocalReference<jobject>(BoxPrimitive(mh.GetReturnType()->GetPrimitiveType(), value));
}
-bool VerifyObjectInClass(Object* o, Class* c) {
+bool VerifyObjectInClass(mirror::Object* o, mirror::Class* c) {
const char* exception = NULL;
if (o == NULL) {
exception = "Ljava/lang/NullPointerException;";
@@ -194,7 +201,7 @@
return false;
}
-Object* BoxPrimitive(Primitive::Type src_class, const JValue& value) {
+mirror::Object* BoxPrimitive(Primitive::Type src_class, const JValue& value) {
if (src_class == Primitive::kPrimNot) {
return value.GetL();
}
@@ -242,7 +249,7 @@
return result.GetL();
}
-static std::string UnboxingFailureKind(AbstractMethod* m, int index, Field* f)
+static std::string UnboxingFailureKind(mirror::AbstractMethod* m, int index, mirror::Field* f)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (m != NULL && index != -1) {
++index; // Humans count from 1.
@@ -254,8 +261,8 @@
return "result";
}
-static bool UnboxPrimitive(Object* o, Class* dst_class, JValue& unboxed_value, AbstractMethod* m,
- int index, Field* f)
+static bool UnboxPrimitive(mirror::Object* o, mirror::Class* dst_class, JValue& unboxed_value,
+ mirror::AbstractMethod* m, int index, mirror::Field* f)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (!dst_class->IsPrimitive()) {
if (o != NULL && !o->InstanceOf(dst_class)) {
@@ -285,9 +292,9 @@
JValue boxed_value;
std::string src_descriptor(ClassHelper(o->GetClass()).GetDescriptor());
- Class* src_class = NULL;
+ mirror::Class* src_class = NULL;
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Field* primitive_field = o->GetClass()->GetIFields()->Get(0);
+ mirror::Field* primitive_field = o->GetClass()->GetIFields()->Get(0);
if (src_descriptor == "Ljava/lang/Boolean;") {
src_class = class_linker->FindPrimitiveClass('Z');
boxed_value.SetZ(primitive_field->GetBoolean(o));
@@ -325,17 +332,19 @@
boxed_value, unboxed_value);
}
-bool UnboxPrimitiveForArgument(Object* o, Class* dst_class, JValue& unboxed_value, AbstractMethod* m, size_t index) {
+bool UnboxPrimitiveForArgument(mirror::Object* o, mirror::Class* dst_class, JValue& unboxed_value,
+ mirror::AbstractMethod* m, size_t index) {
CHECK(m != NULL);
return UnboxPrimitive(o, dst_class, unboxed_value, m, index, NULL);
}
-bool UnboxPrimitiveForField(Object* o, Class* dst_class, JValue& unboxed_value, Field* f) {
+bool UnboxPrimitiveForField(mirror::Object* o, mirror::Class* dst_class, JValue& unboxed_value,
+ mirror::Field* f) {
CHECK(f != NULL);
return UnboxPrimitive(o, dst_class, unboxed_value, NULL, -1, f);
}
-bool UnboxPrimitiveForResult(Object* o, Class* dst_class, JValue& unboxed_value) {
+bool UnboxPrimitiveForResult(mirror::Object* o, mirror::Class* dst_class, JValue& unboxed_value) {
return UnboxPrimitive(o, dst_class, unboxed_value, NULL, -1, NULL);
}
diff --git a/src/reflection.h b/src/reflection.h
index 601543f..8f32243 100644
--- a/src/reflection.h
+++ b/src/reflection.h
@@ -21,22 +21,24 @@
#include "primitive.h"
namespace art {
-
+namespace mirror {
+class AbstractMethod;
class Class;
class Field;
-union JValue;
-class AbstractMethod;
class Object;
+} // namespace mirror
+union JValue;
class ScopedObjectAccess;
-Object* BoxPrimitive(Primitive::Type src_class, const JValue& value)
+mirror::Object* BoxPrimitive(Primitive::Type src_class, const JValue& value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-bool UnboxPrimitiveForArgument(Object* o, Class* dst_class, JValue& unboxed_value,
- AbstractMethod* m, size_t index)
+bool UnboxPrimitiveForArgument(mirror::Object* o, mirror::Class* dst_class, JValue& unboxed_value,
+ mirror::AbstractMethod* m, size_t index)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-bool UnboxPrimitiveForField(Object* o, Class* dst_class, JValue& unboxed_value, Field* f)
+bool UnboxPrimitiveForField(mirror::Object* o, mirror::Class* dst_class, JValue& unboxed_value,
+ mirror::Field* f)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-bool UnboxPrimitiveForResult(Object* o, Class* dst_class, JValue& unboxed_value)
+bool UnboxPrimitiveForResult(mirror::Object* o, mirror::Class* dst_class, JValue& unboxed_value)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool ConvertPrimitiveValue(Primitive::Type src_class, Primitive::Type dst_class, const JValue& src,
@@ -46,7 +48,7 @@
jobject InvokeMethod(const ScopedObjectAccess& soa, jobject method, jobject receiver, jobject args)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-bool VerifyObjectInClass(Object* o, Class* c)
+bool VerifyObjectInClass(mirror::Object* o, mirror::Class* c)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
} // namespace art
diff --git a/src/root_visitor.h b/src/root_visitor.h
new file mode 100644
index 0000000..d53acd3
--- /dev/null
+++ b/src/root_visitor.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_ROOT_VISITOR_H_
+#define ART_SRC_ROOT_VISITOR_H_
+
+namespace art {
+namespace mirror {
+class Object;
+} // namespace mirror
+class StackVisitor;
+
+typedef void (RootVisitor)(const mirror::Object* root, void* arg);
+typedef void (VerifyRootVisitor)(const mirror::Object* root, void* arg, size_t vreg,
+ const StackVisitor* visitor);
+typedef bool (IsMarkedTester)(const mirror::Object* object, void* arg);
+
+} // namespace art
+
+#endif // ART_SRC_ROOT_VISITOR_H_
diff --git a/src/runtime.cc b/src/runtime.cc
index 5c73fef..085a9bf 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -24,17 +24,24 @@
#include <limits>
#include <vector>
+#include "atomic.h"
#include "class_linker.h"
-#include "class_loader.h"
#include "constants_arm.h"
#include "constants_mips.h"
#include "constants_x86.h"
#include "debugger.h"
+#include "gc/card_table-inl.h"
#include "heap.h"
#include "image.h"
#include "instrumentation.h"
#include "intern_table.h"
#include "jni_internal.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/array.h"
+#include "mirror/class_loader.h"
+#include "mirror/field.h"
+#include "mirror/object-inl.h"
+#include "mirror/throwable.h"
#include "monitor.h"
#include "oat_file.h"
#include "ScopedLocalRef.h"
@@ -627,23 +634,25 @@
ScopedObjectAccess soa(Thread::Current());
- Class* class_loader_class = soa.Decode<Class*>(WellKnownClasses::java_lang_ClassLoader);
+ mirror::Class* class_loader_class =
+ soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_ClassLoader);
CHECK(Runtime::Current()->GetClassLinker()->EnsureInitialized(class_loader_class, true, true));
- AbstractMethod* getSystemClassLoader = class_loader_class->FindDirectMethod("getSystemClassLoader", "()Ljava/lang/ClassLoader;");
+ mirror::AbstractMethod* getSystemClassLoader =
+ class_loader_class->FindDirectMethod("getSystemClassLoader", "()Ljava/lang/ClassLoader;");
CHECK(getSystemClassLoader != NULL);
- ClassLoader* class_loader =
- down_cast<ClassLoader*>(InvokeWithJValues(soa, NULL, getSystemClassLoader, NULL).GetL());
+ mirror::ClassLoader* class_loader =
+ down_cast<mirror::ClassLoader*>(InvokeWithJValues(soa, NULL, getSystemClassLoader, NULL).GetL());
CHECK(class_loader != NULL);
soa.Self()->SetClassLoaderOverride(class_loader);
- Class* thread_class = soa.Decode<Class*>(WellKnownClasses::java_lang_Thread);
+ mirror::Class* thread_class = soa.Decode<mirror::Class*>(WellKnownClasses::java_lang_Thread);
CHECK(Runtime::Current()->GetClassLinker()->EnsureInitialized(thread_class, true, true));
- Field* contextClassLoader = thread_class->FindDeclaredInstanceField("contextClassLoader",
- "Ljava/lang/ClassLoader;");
+ mirror::Field* contextClassLoader = thread_class->FindDeclaredInstanceField("contextClassLoader",
+ "Ljava/lang/ClassLoader;");
CHECK(contextClassLoader != NULL);
contextClassLoader->SetObject(soa.Self()->GetPeer(), class_loader);
@@ -1015,7 +1024,7 @@
thread_list_->Unregister(self);
}
-void Runtime::VisitConcurrentRoots(Heap::RootVisitor* visitor, void* arg) {
+void Runtime::VisitConcurrentRoots(RootVisitor* visitor, void* arg) {
if (intern_table_->IsDirty()) {
intern_table_->VisitRoots(visitor, arg);
}
@@ -1024,7 +1033,7 @@
}
}
-void Runtime::VisitNonThreadRoots(Heap::RootVisitor* visitor, void* arg) {
+void Runtime::VisitNonThreadRoots(RootVisitor* visitor, void* arg) {
Dbg::VisitRoots(visitor, arg);
java_vm_->VisitRoots(visitor, arg);
if (pre_allocated_OutOfMemoryError_ != NULL) {
@@ -1041,7 +1050,7 @@
}
}
-void Runtime::VisitNonConcurrentRoots(Heap::RootVisitor* visitor, void* arg) {
+void Runtime::VisitNonConcurrentRoots(RootVisitor* visitor, void* arg) {
thread_list_->VisitRoots(visitor, arg);
VisitNonThreadRoots(visitor, arg);
}
@@ -1053,48 +1062,50 @@
class_linker_->Dirty();
}
-void Runtime::VisitRoots(Heap::RootVisitor* visitor, void* arg) {
+void Runtime::VisitRoots(RootVisitor* visitor, void* arg) {
VisitConcurrentRoots(visitor, arg);
VisitNonConcurrentRoots(visitor, arg);
}
-void Runtime::SetJniDlsymLookupStub(ByteArray* jni_stub_array) {
+void Runtime::SetJniDlsymLookupStub(mirror::ByteArray* jni_stub_array) {
CHECK(jni_stub_array != NULL) << " jni_stub_array=" << jni_stub_array;
CHECK(jni_stub_array_ == NULL || jni_stub_array_ == jni_stub_array)
<< "jni_stub_array_=" << jni_stub_array_ << " jni_stub_array=" << jni_stub_array;
jni_stub_array_ = jni_stub_array;
}
-void Runtime::SetAbstractMethodErrorStubArray(ByteArray* abstract_method_error_stub_array) {
+void Runtime::SetAbstractMethodErrorStubArray(mirror::ByteArray* abstract_method_error_stub_array) {
CHECK(abstract_method_error_stub_array != NULL);
CHECK(abstract_method_error_stub_array_ == NULL || abstract_method_error_stub_array_ == abstract_method_error_stub_array);
abstract_method_error_stub_array_ = abstract_method_error_stub_array;
}
-void Runtime::SetResolutionStubArray(ByteArray* resolution_stub_array, TrampolineType type) {
+void Runtime::SetResolutionStubArray(mirror::ByteArray* resolution_stub_array, TrampolineType type) {
CHECK(resolution_stub_array != NULL);
CHECK(!HasResolutionStubArray(type) || resolution_stub_array_[type] == resolution_stub_array);
resolution_stub_array_[type] = resolution_stub_array;
}
-AbstractMethod* Runtime::CreateResolutionMethod() {
- Class* method_class = AbstractMethod::GetMethodClass();
+mirror::AbstractMethod* Runtime::CreateResolutionMethod() {
+ mirror::Class* method_class = mirror::AbstractMethod::GetMethodClass();
Thread* self = Thread::Current();
- SirtRef<AbstractMethod> method(self, down_cast<AbstractMethod*>(method_class->AllocObject(self)));
+ SirtRef<mirror::AbstractMethod>
+ method(self, down_cast<mirror::AbstractMethod*>(method_class->AllocObject(self)));
method->SetDeclaringClass(method_class);
// TODO: use a special method for resolution method saves
method->SetDexMethodIndex(DexFile::kDexNoIndex16);
- ByteArray* unknown_resolution_stub = GetResolutionStubArray(kUnknownMethod);
+ mirror::ByteArray* unknown_resolution_stub = GetResolutionStubArray(kUnknownMethod);
CHECK(unknown_resolution_stub != NULL);
method->SetCode(unknown_resolution_stub->GetData());
return method.get();
}
-AbstractMethod* Runtime::CreateCalleeSaveMethod(InstructionSet instruction_set,
- CalleeSaveType type) {
- Class* method_class = AbstractMethod::GetMethodClass();
+mirror::AbstractMethod* Runtime::CreateCalleeSaveMethod(InstructionSet instruction_set,
+ CalleeSaveType type) {
+ mirror::Class* method_class = mirror::AbstractMethod::GetMethodClass();
Thread* self = Thread::Current();
- SirtRef<AbstractMethod> method(self, down_cast<AbstractMethod*>(method_class->AllocObject(self)));
+ SirtRef<mirror::AbstractMethod>
+ method(self, down_cast<mirror::AbstractMethod*>(method_class->AllocObject(self)));
method->SetDeclaringClass(method_class);
// TODO: use a special method for callee saves
method->SetDexMethodIndex(DexFile::kDexNoIndex16);
@@ -1154,7 +1165,7 @@
return method.get();
}
-void Runtime::SetCalleeSaveMethod(AbstractMethod* method, CalleeSaveType type) {
+void Runtime::SetCalleeSaveMethod(mirror::AbstractMethod* method, CalleeSaveType type) {
DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastCalleeSaveType));
callee_save_methods_[type] = method;
}
diff --git a/src/runtime.h b/src/runtime.h
index 84cc826..1d71c13 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -32,6 +32,7 @@
#include "instruction_set.h"
#include "jobject_comparator.h"
#include "locks.h"
+#include "root_visitor.h"
#include "runtime_stats.h"
#include "safe_map.h"
@@ -41,21 +42,23 @@
namespace art {
+namespace mirror {
+class AbstractMethod;
+class ClassLoader;
template<class T> class PrimitiveArray;
typedef PrimitiveArray<int8_t> ByteArray;
+class String;
+class Throwable;
+} // namespace mirror
class ClassLinker;
-class ClassLoader;
class DexFile;
class Heap;
class Instrumentation;
class InternTable;
struct JavaVMExt;
-class AbstractMethod;
class MonitorList;
class SignalCatcher;
-class String;
class ThreadList;
-class Throwable;
class Trace;
class Runtime {
@@ -215,7 +218,7 @@
return monitor_list_;
}
- Throwable* GetPreAllocatedOutOfMemoryError() {
+ mirror::Throwable* GetPreAllocatedOutOfMemoryError() {
return pre_allocated_OutOfMemoryError_;
}
@@ -235,40 +238,40 @@
void DirtyRoots();
// Visit all the roots.
- void VisitRoots(Heap::RootVisitor* visitor, void* arg)
+ void VisitRoots(RootVisitor* visitor, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Visit all of the roots we can do safely do concurrently.
- void VisitConcurrentRoots(Heap::RootVisitor* visitor, void* arg);
+ void VisitConcurrentRoots(RootVisitor* visitor, void* arg);
// Visit all of the non thread roots, we can do this with mutators unpaused.
- void VisitNonThreadRoots(Heap::RootVisitor* visitor, void* arg);
+ void VisitNonThreadRoots(RootVisitor* visitor, void* arg);
// Visit all other roots which must be done with mutators suspended.
- void VisitNonConcurrentRoots(Heap::RootVisitor* visitor, void* arg)
+ void VisitNonConcurrentRoots(RootVisitor* visitor, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool HasJniDlsymLookupStub() const {
return jni_stub_array_ != NULL;
}
- ByteArray* GetJniDlsymLookupStub() const {
+ mirror::ByteArray* GetJniDlsymLookupStub() const {
CHECK(HasJniDlsymLookupStub());
return jni_stub_array_;
}
- void SetJniDlsymLookupStub(ByteArray* jni_stub_array);
+ void SetJniDlsymLookupStub(mirror::ByteArray* jni_stub_array);
bool HasAbstractMethodErrorStubArray() const {
return abstract_method_error_stub_array_ != NULL;
}
- ByteArray* GetAbstractMethodErrorStubArray() const {
+ mirror::ByteArray* GetAbstractMethodErrorStubArray() const {
CHECK(abstract_method_error_stub_array_ != NULL);
return abstract_method_error_stub_array_;
}
- void SetAbstractMethodErrorStubArray(ByteArray* abstract_method_error_stub_array);
+ void SetAbstractMethodErrorStubArray(mirror::ByteArray* abstract_method_error_stub_array);
enum TrampolineType {
kStaticMethod,
@@ -280,16 +283,16 @@
return resolution_stub_array_[type] != NULL;
}
- ByteArray* GetResolutionStubArray(TrampolineType type) const {
+ mirror::ByteArray* GetResolutionStubArray(TrampolineType type) const {
CHECK(HasResolutionStubArray(type));
DCHECK_LT(static_cast<int>(type), static_cast<int>(kLastTrampolineMethodType));
return resolution_stub_array_[type];
}
- void SetResolutionStubArray(ByteArray* resolution_stub_array, TrampolineType type);
+ void SetResolutionStubArray(mirror::ByteArray* resolution_stub_array, TrampolineType type);
// Returns a special method that calls into a trampoline for runtime method resolution
- AbstractMethod* GetResolutionMethod() const {
+ mirror::AbstractMethod* GetResolutionMethod() const {
CHECK(HasResolutionMethod());
return resolution_method_;
}
@@ -298,11 +301,11 @@
return resolution_method_ != NULL;
}
- void SetResolutionMethod(AbstractMethod* method) {
+ void SetResolutionMethod(mirror::AbstractMethod* method) {
resolution_method_ = method;
}
- AbstractMethod* CreateResolutionMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::AbstractMethod* CreateResolutionMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Returns a special method that describes all callee saves being spilled to the stack.
enum CalleeSaveType {
@@ -316,20 +319,21 @@
return callee_save_methods_[type] != NULL;
}
- AbstractMethod* GetCalleeSaveMethod(CalleeSaveType type) const {
+ mirror::AbstractMethod* GetCalleeSaveMethod(CalleeSaveType type) const {
DCHECK(HasCalleeSaveMethod(type));
return callee_save_methods_[type];
}
- void SetCalleeSaveMethod(AbstractMethod* method, CalleeSaveType type);
+ void SetCalleeSaveMethod(mirror::AbstractMethod* method, CalleeSaveType type);
- AbstractMethod* CreateCalleeSaveMethod(InstructionSet instruction_set, CalleeSaveType type)
+ mirror::AbstractMethod* CreateCalleeSaveMethod(InstructionSet instruction_set,
+ CalleeSaveType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- AbstractMethod* CreateRefOnlyCalleeSaveMethod(InstructionSet instruction_set)
+ mirror::AbstractMethod* CreateRefOnlyCalleeSaveMethod(InstructionSet instruction_set)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- AbstractMethod* CreateRefAndArgsCalleeSaveMethod(InstructionSet instruction_set)
+ mirror::AbstractMethod* CreateRefAndArgsCalleeSaveMethod(InstructionSet instruction_set)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
int32_t GetStat(int kind);
@@ -419,20 +423,20 @@
JavaVMExt* java_vm_;
- Throwable* pre_allocated_OutOfMemoryError_;
+ mirror::Throwable* pre_allocated_OutOfMemoryError_;
- ByteArray* jni_stub_array_;
+ mirror::ByteArray* jni_stub_array_;
- ByteArray* abstract_method_error_stub_array_;
+ mirror::ByteArray* abstract_method_error_stub_array_;
- ByteArray* resolution_stub_array_[kLastTrampolineMethodType];
+ mirror::ByteArray* resolution_stub_array_[kLastTrampolineMethodType];
- AbstractMethod* callee_save_methods_[kLastCalleeSaveType];
+ mirror::AbstractMethod* callee_save_methods_[kLastCalleeSaveType];
- AbstractMethod* resolution_method_;
+ mirror::AbstractMethod* resolution_method_;
// As returned by ClassLoader.getSystemClassLoader()
- ClassLoader* system_class_loader_;
+ mirror::ClassLoader* system_class_loader_;
// A non-zero value indicates that a thread has been created but not yet initialized. Guarded by
// the shutdown lock so that threads aren't born while we're shutting down.
diff --git a/src/runtime_support.cc b/src/runtime_support.cc
index b276917..84a19cf 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -16,6 +16,14 @@
#include "runtime_support.h"
+#include "class_linker-inl.h"
+#include "gc/card_table-inl.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/class-inl.h"
+#include "mirror/field-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
+#include "mirror/proxy.h"
#include "reflection.h"
#include "scoped_thread_state_change.h"
#include "ScopedLocalRef.h"
@@ -92,13 +100,14 @@
namespace art {
// Helper function to allocate array for FILLED_NEW_ARRAY.
-Array* CheckAndAllocArrayFromCode(uint32_t type_idx, AbstractMethod* method, int32_t component_count,
- Thread* self, bool access_check) {
+mirror::Array* CheckAndAllocArrayFromCode(uint32_t type_idx, mirror::AbstractMethod* method,
+ int32_t component_count, Thread* self,
+ bool access_check) {
if (UNLIKELY(component_count < 0)) {
self->ThrowNewExceptionF("Ljava/lang/NegativeArraySizeException;", "%d", component_count);
return NULL; // Failure
}
- Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx);
+ mirror::Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx);
if (UNLIKELY(klass == NULL)) { // Not in dex cache so try to resolve
klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
if (klass == NULL) { // Error
@@ -119,19 +128,19 @@
return NULL; // Failure
} else {
if (access_check) {
- Class* referrer = method->GetDeclaringClass();
+ mirror::Class* referrer = method->GetDeclaringClass();
if (UNLIKELY(!referrer->CanAccess(klass))) {
ThrowIllegalAccessErrorClass(referrer, klass);
return NULL; // Failure
}
}
DCHECK(klass->IsArrayClass()) << PrettyClass(klass);
- return Array::Alloc(self, klass, component_count);
+ return mirror::Array::Alloc(self, klass, component_count);
}
}
-Field* FindFieldFromCode(uint32_t field_idx, const AbstractMethod* referrer, Thread* self,
- FindFieldType type, size_t expected_size) {
+mirror::Field* FindFieldFromCode(uint32_t field_idx, const mirror::AbstractMethod* referrer,
+ Thread* self, FindFieldType type, size_t expected_size) {
bool is_primitive;
bool is_set;
bool is_static;
@@ -147,7 +156,7 @@
default: is_primitive = true; is_set = true; is_static = true; break;
}
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Field* resolved_field = class_linker->ResolveField(field_idx, referrer, is_static);
+ mirror::Field* resolved_field = class_linker->ResolveField(field_idx, referrer, is_static);
if (UNLIKELY(resolved_field == NULL)) {
DCHECK(self->IsExceptionPending()); // Throw exception and unwind.
return NULL; // Failure.
@@ -156,8 +165,8 @@
ThrowIncompatibleClassChangeErrorField(resolved_field, is_static, referrer);
return NULL;
}
- Class* fields_class = resolved_field->GetDeclaringClass();
- Class* referring_class = referrer->GetDeclaringClass();
+ mirror::Class* fields_class = resolved_field->GetDeclaringClass();
+ mirror::Class* referring_class = referrer->GetDeclaringClass();
if (UNLIKELY(!referring_class->CanAccess(fields_class) ||
!referring_class->CanAccessMember(fields_class,
resolved_field->GetAccessFlags()))) {
@@ -210,11 +219,12 @@
}
// Slow path method resolution
-AbstractMethod* FindMethodFromCode(uint32_t method_idx, Object* this_object, AbstractMethod* referrer,
- Thread* self, bool access_check, InvokeType type) {
+mirror::AbstractMethod* FindMethodFromCode(uint32_t method_idx, mirror::Object* this_object,
+ mirror::AbstractMethod* referrer,
+ Thread* self, bool access_check, InvokeType type) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
bool is_direct = type == kStatic || type == kDirect;
- AbstractMethod* resolved_method = class_linker->ResolveMethod(method_idx, referrer, type);
+ mirror::AbstractMethod* resolved_method = class_linker->ResolveMethod(method_idx, referrer, type);
if (UNLIKELY(resolved_method == NULL)) {
DCHECK(self->IsExceptionPending()); // Throw exception and unwind.
return NULL; // Failure.
@@ -228,7 +238,7 @@
if (is_direct) {
return resolved_method;
} else if (type == kInterface) {
- AbstractMethod* interface_method =
+ mirror::AbstractMethod* interface_method =
this_object->GetClass()->FindVirtualMethodForInterface(resolved_method);
if (UNLIKELY(interface_method == NULL)) {
ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(resolved_method, this_object,
@@ -238,7 +248,7 @@
return interface_method;
}
} else {
- ObjectArray<AbstractMethod>* vtable;
+ mirror::ObjectArray<mirror::AbstractMethod>* vtable;
uint16_t vtable_index = resolved_method->GetMethodIndex();
if (type == kSuper) {
vtable = referrer->GetDeclaringClass()->GetSuperClass()->GetVTable();
@@ -255,8 +265,8 @@
referrer);
return NULL; // Failure.
}
- Class* methods_class = resolved_method->GetDeclaringClass();
- Class* referring_class = referrer->GetDeclaringClass();
+ mirror::Class* methods_class = resolved_method->GetDeclaringClass();
+ mirror::Class* referring_class = referrer->GetDeclaringClass();
if (UNLIKELY(!referring_class->CanAccess(methods_class) ||
!referring_class->CanAccessMember(methods_class,
resolved_method->GetAccessFlags()))) {
@@ -280,7 +290,7 @@
if (is_direct) {
return resolved_method;
} else if (type == kInterface) {
- AbstractMethod* interface_method =
+ mirror::AbstractMethod* interface_method =
this_object->GetClass()->FindVirtualMethodForInterface(resolved_method);
if (UNLIKELY(interface_method == NULL)) {
ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(resolved_method, this_object,
@@ -290,10 +300,10 @@
return interface_method;
}
} else {
- ObjectArray<AbstractMethod>* vtable;
+ mirror::ObjectArray<mirror::AbstractMethod>* vtable;
uint16_t vtable_index = resolved_method->GetMethodIndex();
if (type == kSuper) {
- Class* super_class = referring_class->GetSuperClass();
+ mirror::Class* super_class = referring_class->GetSuperClass();
if (LIKELY(super_class != NULL)) {
vtable = referring_class->GetSuperClass()->GetVTable();
} else {
@@ -317,16 +327,16 @@
}
}
-Class* ResolveVerifyAndClinit(uint32_t type_idx, const AbstractMethod* referrer, Thread* self,
- bool can_run_clinit, bool verify_access) {
+mirror::Class* ResolveVerifyAndClinit(uint32_t type_idx, const mirror::AbstractMethod* referrer,
+ Thread* self, bool can_run_clinit, bool verify_access) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Class* klass = class_linker->ResolveType(type_idx, referrer);
+ mirror::Class* klass = class_linker->ResolveType(type_idx, referrer);
if (UNLIKELY(klass == NULL)) {
CHECK(self->IsExceptionPending());
return NULL; // Failure - Indicate to caller to deliver exception
}
// Perform access check if necessary.
- Class* referring_class = referrer->GetDeclaringClass();
+ mirror::Class* referring_class = referrer->GetDeclaringClass();
if (verify_access && UNLIKELY(!referring_class->CanAccess(klass))) {
ThrowIllegalAccessErrorClass(referring_class, klass);
return NULL; // Failure - Indicate to caller to deliver exception
@@ -396,12 +406,12 @@
} else {
JValue jv;
jv.SetJ(args.at(i).j);
- Object* val = BoxPrimitive(Primitive::GetType(shorty[i + 1]), jv);
+ mirror::Object* val = BoxPrimitive(Primitive::GetType(shorty[i + 1]), jv);
if (val == NULL) {
CHECK(soa.Self()->IsExceptionPending());
return zero;
}
- soa.Decode<ObjectArray<Object>* >(args_jobj)->Set(i, val);
+ soa.Decode<mirror::ObjectArray<mirror::Object>* >(args_jobj)->Set(i, val);
}
}
}
@@ -425,9 +435,9 @@
return zero;
} else {
JValue result_unboxed;
- MethodHelper mh(soa.Decode<AbstractMethod*>(interface_method_jobj));
- Class* result_type = mh.GetReturnType();
- Object* result_ref = soa.Decode<Object*>(result);
+ MethodHelper mh(soa.Decode<mirror::AbstractMethod*>(interface_method_jobj));
+ mirror::Class* result_type = mh.GetReturnType();
+ mirror::Object* result_ref = soa.Decode<mirror::Object*>(result);
bool unboxed_okay = UnboxPrimitiveForResult(result_ref, result_type, result_unboxed);
if (!unboxed_okay) {
soa.Self()->ThrowNewWrappedException("Ljava/lang/ClassCastException;",
@@ -441,12 +451,14 @@
} else {
// In the case of checked exceptions that aren't declared, the exception must be wrapped by
// a UndeclaredThrowableException.
- Throwable* exception = soa.Self()->GetException();
+ mirror::Throwable* exception = soa.Self()->GetException();
if (exception->IsCheckedException()) {
- Object* rcvr = soa.Decode<Object*>(rcvr_jobj);
- SynthesizedProxyClass* proxy_class = down_cast<SynthesizedProxyClass*>(rcvr->GetClass());
- AbstractMethod* interface_method = soa.Decode<AbstractMethod*>(interface_method_jobj);
- AbstractMethod* proxy_method =
+ mirror::Object* rcvr = soa.Decode<mirror::Object*>(rcvr_jobj);
+ mirror::SynthesizedProxyClass* proxy_class =
+ down_cast<mirror::SynthesizedProxyClass*>(rcvr->GetClass());
+ mirror::AbstractMethod* interface_method =
+ soa.Decode<mirror::AbstractMethod*>(interface_method_jobj);
+ mirror::AbstractMethod* proxy_method =
rcvr->GetClass()->FindVirtualMethodForInterface(interface_method);
int throws_index = -1;
size_t num_virt_methods = proxy_class->NumVirtualMethods();
@@ -457,11 +469,11 @@
}
}
CHECK_NE(throws_index, -1);
- ObjectArray<Class>* declared_exceptions = proxy_class->GetThrows()->Get(throws_index);
- Class* exception_class = exception->GetClass();
+ mirror::ObjectArray<mirror::Class>* declared_exceptions = proxy_class->GetThrows()->Get(throws_index);
+ mirror::Class* exception_class = exception->GetClass();
bool declares_exception = false;
for (int i = 0; i < declared_exceptions->GetLength() && !declares_exception; i++) {
- Class* declared_exception = declared_exceptions->Get(i);
+ mirror::Class* declared_exception = declared_exceptions->Get(i);
declares_exception = declared_exception->IsAssignableFrom(exception_class);
}
if (!declares_exception) {
diff --git a/src/runtime_support.h b/src/runtime_support.h
index 1c8d174..a504237 100644
--- a/src/runtime_support.h
+++ b/src/runtime_support.h
@@ -23,10 +23,11 @@
#include "indirect_reference_table.h"
#include "invoke_type.h"
#include "jni_internal.h"
-#include "object.h"
+#include "mirror/abstract_method.h"
+#include "mirror/array.h"
+#include "mirror/throwable.h"
#include "object_utils.h"
#include "thread.h"
-#include "verifier/method_verifier.h"
extern "C" void art_interpreter_invoke_handler();
extern "C" void art_proxy_invoke_handler();
@@ -40,21 +41,21 @@
extern "C" int32_t art_f2i(float f);
namespace art {
-
-class Array;
+namespace mirror {
class Class;
class Field;
-class AbstractMethod;
class Object;
+}
// Given the context of a calling Method, use its DexCache to resolve a type to a Class. If it
// cannot be resolved, throw an error. If it can, use it to create an instance.
// When verification/compiler hasn't been able to verify access, optionally perform an access
// check.
-static inline Object* AllocObjectFromCode(uint32_t type_idx, AbstractMethod* method, Thread* self,
- bool access_check)
+static inline mirror::Object* AllocObjectFromCode(uint32_t type_idx, mirror::AbstractMethod* method,
+ Thread* self,
+ bool access_check)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx);
+ mirror::Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx);
Runtime* runtime = Runtime::Current();
if (UNLIKELY(klass == NULL)) {
klass = runtime->GetClassLinker()->ResolveType(type_idx, method);
@@ -69,7 +70,7 @@
PrettyDescriptor(klass).c_str());
return NULL; // Failure
}
- Class* referrer = method->GetDeclaringClass();
+ mirror::Class* referrer = method->GetDeclaringClass();
if (UNLIKELY(!referrer->CanAccess(klass))) {
ThrowIllegalAccessErrorClass(referrer, klass);
return NULL; // Failure
@@ -87,14 +88,15 @@
// it cannot be resolved, throw an error. If it can, use it to create an array.
// 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,
- Thread* self, bool access_check)
+static inline mirror::Array* AllocArrayFromCode(uint32_t type_idx, mirror::AbstractMethod* method,
+ int32_t component_count,
+ Thread* self, bool access_check)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (UNLIKELY(component_count < 0)) {
self->ThrowNewExceptionF("Ljava/lang/NegativeArraySizeException;", "%d", component_count);
return NULL; // Failure
}
- Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx);
+ mirror::Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx);
if (UNLIKELY(klass == NULL)) { // Not in dex cache so try to resolve
klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method);
if (klass == NULL) { // Error
@@ -104,17 +106,18 @@
CHECK(klass->IsArrayClass()) << PrettyClass(klass);
}
if (access_check) {
- Class* referrer = method->GetDeclaringClass();
+ mirror::Class* referrer = method->GetDeclaringClass();
if (UNLIKELY(!referrer->CanAccess(klass))) {
ThrowIllegalAccessErrorClass(referrer, klass);
return NULL; // Failure
}
}
- return Array::Alloc(self, klass, component_count);
+ return mirror::Array::Alloc(self, klass, component_count);
}
-extern Array* CheckAndAllocArrayFromCode(uint32_t type_idx, AbstractMethod* method, int32_t component_count,
- Thread* self, bool access_check)
+extern mirror::Array* CheckAndAllocArrayFromCode(uint32_t type_idx, mirror::AbstractMethod* method,
+ int32_t component_count,
+ Thread* self, bool access_check)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Type of find field operation for fast and slow case.
@@ -130,19 +133,21 @@
};
// Slow field find that can initialize classes and may throw exceptions.
-extern Field* FindFieldFromCode(uint32_t field_idx, const AbstractMethod* referrer, Thread* self,
- FindFieldType type, size_t expected_size)
+extern mirror::Field* FindFieldFromCode(uint32_t field_idx, const mirror::AbstractMethod* referrer,
+ Thread* self, FindFieldType type, size_t expected_size)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Fast path field resolution that can't initialize classes or throw exceptions.
-static inline Field* FindFieldFast(uint32_t field_idx, const AbstractMethod* referrer,
- FindFieldType type, size_t expected_size)
+static inline mirror::Field* FindFieldFast(uint32_t field_idx,
+ const mirror::AbstractMethod* referrer,
+ FindFieldType type, size_t expected_size)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Field* resolved_field = referrer->GetDeclaringClass()->GetDexCache()->GetResolvedField(field_idx);
+ mirror::Field* resolved_field =
+ referrer->GetDeclaringClass()->GetDexCache()->GetResolvedField(field_idx);
if (UNLIKELY(resolved_field == NULL)) {
return NULL;
}
- Class* fields_class = resolved_field->GetDeclaringClass();
+ mirror::Class* fields_class = resolved_field->GetDeclaringClass();
// Check class is initiliazed or initializing.
if (UNLIKELY(!fields_class->IsInitializing())) {
return NULL;
@@ -167,7 +172,7 @@
// Incompatible class change.
return NULL;
}
- Class* referring_class = referrer->GetDeclaringClass();
+ mirror::Class* referring_class = referrer->GetDeclaringClass();
if (UNLIKELY(!referring_class->CanAccess(fields_class) ||
!referring_class->CanAccessMember(fields_class,
resolved_field->GetAccessFlags()) ||
@@ -184,14 +189,16 @@
}
// Fast path method resolution that can't throw exceptions.
-static inline AbstractMethod* FindMethodFast(uint32_t method_idx, Object* this_object,
- const AbstractMethod* referrer, bool access_check, InvokeType type)
+static inline mirror::AbstractMethod* FindMethodFast(uint32_t method_idx,
+ mirror::Object* this_object,
+ const mirror::AbstractMethod* referrer,
+ bool access_check, InvokeType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
bool is_direct = type == kStatic || type == kDirect;
if (UNLIKELY(this_object == NULL && !is_direct)) {
return NULL;
}
- AbstractMethod* resolved_method =
+ mirror::AbstractMethod* resolved_method =
referrer->GetDeclaringClass()->GetDexCache()->GetResolvedMethod(method_idx);
if (UNLIKELY(resolved_method == NULL)) {
return NULL;
@@ -202,8 +209,8 @@
if (UNLIKELY(icce)) {
return NULL;
}
- Class* methods_class = resolved_method->GetDeclaringClass();
- Class* referring_class = referrer->GetDeclaringClass();
+ mirror::Class* methods_class = resolved_method->GetDeclaringClass();
+ mirror::Class* referring_class = referrer->GetDeclaringClass();
if (UNLIKELY(!referring_class->CanAccess(methods_class) ||
!referring_class->CanAccessMember(methods_class,
resolved_method->GetAccessFlags()))) {
@@ -224,17 +231,20 @@
}
}
-extern AbstractMethod* FindMethodFromCode(uint32_t method_idx, Object* this_object, AbstractMethod* referrer,
- Thread* self, bool access_check, InvokeType type)
+extern mirror::AbstractMethod* FindMethodFromCode(uint32_t method_idx, mirror::Object* this_object,
+ mirror::AbstractMethod* referrer,
+ Thread* self, bool access_check, InvokeType type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-extern Class* ResolveVerifyAndClinit(uint32_t type_idx, const AbstractMethod* referrer, Thread* self,
- bool can_run_clinit, bool verify_access)
+extern mirror::Class* ResolveVerifyAndClinit(uint32_t type_idx,
+ const mirror::AbstractMethod* referrer, Thread* self,
+ bool can_run_clinit, bool verify_access)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
extern void ThrowStackOverflowError(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
-static inline String* ResolveStringFromCode(const AbstractMethod* referrer, uint32_t string_idx)
+static inline mirror::String* ResolveStringFromCode(const mirror::AbstractMethod* referrer,
+ uint32_t string_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
return class_linker->ResolveString(string_idx, referrer);
@@ -244,7 +254,7 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
UNLOCK_FUNCTION(monitor_lock_) {
// Save any pending exception over monitor exit call.
- Throwable* saved_exception = NULL;
+ mirror::Throwable* saved_exception = NULL;
if (UNLIKELY(self->IsExceptionPending())) {
saved_exception = self->GetException();
self->ClearException();
@@ -263,7 +273,7 @@
}
}
-static inline void CheckReferenceResult(Object* o, Thread* self)
+static inline void CheckReferenceResult(mirror::Object* o, Thread* self)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (o == NULL) {
return;
@@ -273,9 +283,9 @@
PrettyMethod(self->GetCurrentMethod()).c_str());
}
// Make sure that the result is an instance of the type this method was expected to return.
- AbstractMethod* m = self->GetCurrentMethod();
+ mirror::AbstractMethod* m = self->GetCurrentMethod();
MethodHelper mh(m);
- Class* return_type = mh.GetReturnType();
+ mirror::Class* return_type = mh.GetReturnType();
if (!o->InstanceOf(return_type)) {
JniAbortF(NULL, "attempt to return an instance of %s from %s",
diff --git a/src/scoped_thread_state_change.h b/src/scoped_thread_state_change.h
index 5eabbdf..80d47c5 100644
--- a/src/scoped_thread_state_change.h
+++ b/src/scoped_thread_state_change.h
@@ -165,7 +165,7 @@
* passed in), or NULL on failure.
*/
template<typename T>
- T AddLocalReference(Object* obj) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ T AddLocalReference(mirror::Object* obj) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
DCHECK_EQ(thread_state_, kRunnable); // Don't work with raw objects in non-runnable states.
if (obj == NULL) {
return NULL;
@@ -208,7 +208,7 @@
return down_cast<T>(Self()->DecodeJObject(obj));
}
- Field* DecodeField(jfieldID fid) const
+ mirror::Field* DecodeField(jfieldID fid) const
LOCKS_EXCLUDED(JavaVMExt::globals_lock,
JavaVMExt::weak_globals_lock)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -218,10 +218,10 @@
// TODO: we should make these unique weak globals if Field instances can ever move.
UNIMPLEMENTED(WARNING);
#endif
- return reinterpret_cast<Field*>(fid);
+ return reinterpret_cast<mirror::Field*>(fid);
}
- jfieldID EncodeField(Field* field) const
+ jfieldID EncodeField(mirror::Field* field) const
LOCKS_EXCLUDED(JavaVMExt::globals_lock,
JavaVMExt::weak_globals_lock)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -233,7 +233,7 @@
return reinterpret_cast<jfieldID>(field);
}
- AbstractMethod* DecodeMethod(jmethodID mid) const
+ mirror::AbstractMethod* DecodeMethod(jmethodID mid) const
LOCKS_EXCLUDED(JavaVMExt::globals_lock,
JavaVMExt::weak_globals_lock)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -243,10 +243,10 @@
// TODO: we should make these unique weak globals if Method instances can ever move.
UNIMPLEMENTED(WARNING);
#endif
- return reinterpret_cast<AbstractMethod*>(mid);
+ return reinterpret_cast<mirror::AbstractMethod*>(mid);
}
- jmethodID EncodeMethod(AbstractMethod* method) const
+ jmethodID EncodeMethod(mirror::AbstractMethod* method) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Locks::mutator_lock_->AssertSharedHeld(Self());
DCHECK_EQ(thread_state_, kRunnable); // Don't work with raw objects in non-runnable states.
diff --git a/src/stack.cc b/src/stack.cc
index 2e1f4ae..c998f2a 100644
--- a/src/stack.cc
+++ b/src/stack.cc
@@ -18,7 +18,10 @@
#include "compiler.h"
#include "oat/runtime/context.h"
-#include "object.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
#include "object_utils.h"
#include "thread_list.h"
@@ -39,7 +42,7 @@
return count;
}
-bool ManagedStack::ShadowFramesContain(Object** shadow_frame_entry) const {
+bool ManagedStack::ShadowFramesContain(mirror::Object** shadow_frame_entry) const {
for (const ManagedStack* current_fragment = this; current_fragment != NULL;
current_fragment = current_fragment->GetLink()) {
for (ShadowFrame* current_frame = current_fragment->top_shadow_frame_; current_frame != NULL;
@@ -74,7 +77,7 @@
return GetMethod()->NativePcOffset(cur_quick_frame_pc_);
}
-uint32_t StackVisitor::GetVReg(AbstractMethod* m, uint16_t vreg, VRegKind kind) const {
+uint32_t StackVisitor::GetVReg(mirror::AbstractMethod* m, uint16_t vreg, VRegKind kind) const {
if (cur_quick_frame_ != NULL) {
DCHECK(context_ != NULL); // You can't reliably read registers without a context.
DCHECK(m == GetMethod());
@@ -98,7 +101,8 @@
}
}
-void StackVisitor::SetVReg(AbstractMethod* m, uint16_t vreg, uint32_t new_value, VRegKind kind) {
+void StackVisitor::SetVReg(mirror::AbstractMethod* m, uint16_t vreg, uint32_t new_value,
+ VRegKind kind) {
if (cur_quick_frame_ != NULL) {
DCHECK(context_ != NULL); // You can't reliably write registers without a context.
DCHECK(m == GetMethod());
@@ -136,14 +140,14 @@
}
uintptr_t StackVisitor::GetReturnPc() const {
- AbstractMethod** sp = GetCurrentQuickFrame();
+ mirror::AbstractMethod** sp = GetCurrentQuickFrame();
DCHECK(sp != NULL);
byte* pc_addr = reinterpret_cast<byte*>(sp) + GetMethod()->GetReturnPcOffsetInBytes();
return *reinterpret_cast<uintptr_t*>(pc_addr);
}
void StackVisitor::SetReturnPc(uintptr_t new_ret_pc) {
- AbstractMethod** sp = GetCurrentQuickFrame();
+ mirror::AbstractMethod** sp = GetCurrentQuickFrame();
CHECK(sp != NULL);
byte* pc_addr = reinterpret_cast<byte*>(sp) + GetMethod()->GetReturnPcOffsetInBytes();
*reinterpret_cast<uintptr_t*>(pc_addr) = new_ret_pc;
@@ -182,7 +186,7 @@
std::string StackVisitor::DescribeLocation() const {
std::string result("Visiting method '");
- AbstractMethod* m = GetMethod();
+ mirror::AbstractMethod* m = GetMethod();
if (m == NULL) {
return "upcall";
}
@@ -200,9 +204,9 @@
void StackVisitor::SanityCheckFrame() const {
#ifndef NDEBUG
- AbstractMethod* method = GetMethod();
- CHECK(method->GetClass() == AbstractMethod::GetMethodClass() ||
- method->GetClass() == AbstractMethod::GetConstructorClass());
+ mirror::AbstractMethod* method = GetMethod();
+ CHECK(method->GetClass() == mirror::AbstractMethod::GetMethodClass() ||
+ method->GetClass() == mirror::AbstractMethod::GetConstructorClass());
if (cur_quick_frame_ != NULL) {
method->AssertPcIsWithinCode(cur_quick_frame_pc_);
// Frame sanity.
@@ -229,7 +233,7 @@
if (cur_quick_frame_ != NULL) { // Handle quick stack frames.
// Can't be both a shadow and a quick fragment.
DCHECK(current_fragment->GetTopShadowFrame() == NULL);
- AbstractMethod* method = *cur_quick_frame_;
+ mirror::AbstractMethod* method = *cur_quick_frame_;
while (method != NULL) {
SanityCheckFrame();
bool should_continue = VisitFrame();
@@ -259,7 +263,7 @@
}
cur_quick_frame_pc_ = return_pc;
byte* next_frame = reinterpret_cast<byte*>(cur_quick_frame_) + frame_size;
- cur_quick_frame_ = reinterpret_cast<AbstractMethod**>(next_frame);
+ cur_quick_frame_ = reinterpret_cast<mirror::AbstractMethod**>(next_frame);
cur_depth_++;
method = *cur_quick_frame_;
}
diff --git a/src/stack.h b/src/stack.h
index 8d0efe9..c3d20f5 100644
--- a/src/stack.h
+++ b/src/stack.h
@@ -17,11 +17,9 @@
#ifndef ART_SRC_STACK_H_
#define ART_SRC_STACK_H_
-#include "base/macros.h"
#include "dex_file.h"
-#include "heap.h"
#include "instrumentation.h"
-#include "jni.h"
+#include "base/macros.h"
#include "oat/runtime/context.h"
#include <stdint.h>
@@ -29,9 +27,12 @@
namespace art {
+namespace mirror {
class AbstractMethod;
-class Context;
class Object;
+} // namespace mirror
+
+class Context;
class ShadowFrame;
class StackIndirectReferenceTable;
class ScopedObjectAccess;
@@ -59,10 +60,10 @@
public:
// Create ShadowFrame for interpreter.
static ShadowFrame* Create(uint32_t num_vregs, ShadowFrame* link,
- AbstractMethod* method, uint32_t dex_pc) {
+ mirror::AbstractMethod* method, uint32_t dex_pc) {
size_t sz = sizeof(ShadowFrame) +
(sizeof(uint32_t) * num_vregs) +
- (sizeof(Object*) * num_vregs);
+ (sizeof(mirror::Object*) * num_vregs);
uint8_t* memory = new uint8_t[sz];
ShadowFrame* sf = new (memory) ShadowFrame(num_vregs, link, method, dex_pc, true);
return sf;
@@ -121,13 +122,13 @@
return *reinterpret_cast<const double*>(vreg);
}
- Object* GetVRegReference(size_t i) const {
+ mirror::Object* GetVRegReference(size_t i) const {
DCHECK_LT(i, NumberOfVRegs());
if (HasReferenceArray()) {
return References()[i];
} else {
const uint32_t* vreg = &vregs_[i];
- return *reinterpret_cast<Object* const*>(vreg);
+ return *reinterpret_cast<mirror::Object* const*>(vreg);
}
}
@@ -153,26 +154,26 @@
*reinterpret_cast<double*>(vreg) = val;
}
- void SetVRegReference(size_t i, Object* val) {
+ void SetVRegReference(size_t i, mirror::Object* val) {
DCHECK_LT(i, NumberOfVRegs());
uint32_t* vreg = &vregs_[i];
- *reinterpret_cast<Object**>(vreg) = val;
+ *reinterpret_cast<mirror::Object**>(vreg) = val;
if (HasReferenceArray()) {
References()[i] = val;
}
}
- AbstractMethod* GetMethod() const {
+ mirror::AbstractMethod* GetMethod() const {
DCHECK_NE(method_, static_cast<void*>(NULL));
return method_;
}
- void SetMethod(AbstractMethod* method) {
+ void SetMethod(mirror::AbstractMethod* method) {
DCHECK_NE(method, static_cast<void*>(NULL));
method_ = method;
}
- bool Contains(Object** shadow_frame_entry_obj) const {
+ bool Contains(mirror::Object** shadow_frame_entry_obj) const {
if (HasReferenceArray()) {
return ((&References()[0] <= shadow_frame_entry_obj) &&
(shadow_frame_entry_obj <= (&References()[NumberOfVRegs() - 1])));
@@ -204,8 +205,8 @@
}
private:
- ShadowFrame(uint32_t num_vregs, ShadowFrame* link, AbstractMethod* method, uint32_t dex_pc,
- bool has_reference_array)
+ ShadowFrame(uint32_t num_vregs, ShadowFrame* link, mirror::AbstractMethod* method,
+ uint32_t dex_pc, bool has_reference_array)
: number_of_vregs_(num_vregs), link_(link), method_(method), dex_pc_(dex_pc) {
CHECK_LT(num_vregs, static_cast<uint32_t>(kHasReferenceArray));
if (has_reference_array) {
@@ -220,14 +221,14 @@
}
}
- Object* const* References() const {
+ mirror::Object* const* References() const {
DCHECK(HasReferenceArray());
const uint32_t* vreg_end = &vregs_[NumberOfVRegs()];
- return reinterpret_cast<Object* const*>(vreg_end);
+ return reinterpret_cast<mirror::Object* const*>(vreg_end);
}
- Object** References() {
- return const_cast<Object**>(const_cast<const ShadowFrame*>(this)->References());
+ mirror::Object** References() {
+ return const_cast<mirror::Object**>(const_cast<const ShadowFrame*>(this)->References());
}
enum ShadowFrameFlag {
@@ -237,7 +238,7 @@
uint32_t number_of_vregs_;
// Link to previous shadow frame or NULL.
ShadowFrame* link_;
- AbstractMethod* method_;
+ mirror::AbstractMethod* method_;
uint32_t dex_pc_;
uint32_t vregs_[0];
@@ -272,11 +273,11 @@
return link_;
}
- AbstractMethod** GetTopQuickFrame() const {
+ mirror::AbstractMethod** GetTopQuickFrame() const {
return top_quick_frame_;
}
- void SetTopQuickFrame(AbstractMethod** top) {
+ void SetTopQuickFrame(mirror::AbstractMethod** top) {
top_quick_frame_ = top;
}
@@ -320,12 +321,12 @@
size_t NumJniShadowFrameReferences() const;
- bool ShadowFramesContain(Object** shadow_frame_entry) const;
+ bool ShadowFramesContain(mirror::Object** shadow_frame_entry) const;
private:
ManagedStack* link_;
ShadowFrame* top_shadow_frame_;
- AbstractMethod** top_quick_frame_;
+ mirror::AbstractMethod** top_quick_frame_;
uintptr_t top_quick_frame_pc_;
};
@@ -342,7 +343,7 @@
void WalkStack(bool include_transitions = false)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- AbstractMethod* GetMethod() const {
+ mirror::AbstractMethod* GetMethod() const {
if (cur_shadow_frame_ != NULL) {
return cur_shadow_frame_->GetMethod();
} else if (cur_quick_frame_ != NULL) {
@@ -388,16 +389,16 @@
return num_frames_;
}
- uint32_t GetVReg(AbstractMethod* m, uint16_t vreg, VRegKind kind) const
+ uint32_t GetVReg(mirror::AbstractMethod* m, uint16_t vreg, VRegKind kind) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void SetVReg(AbstractMethod* m, uint16_t vreg, uint32_t new_value, VRegKind kind)
+ void SetVReg(mirror::AbstractMethod* m, uint16_t vreg, uint32_t new_value, VRegKind kind)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
uintptr_t GetGPR(uint32_t reg) const;
void SetGPR(uint32_t reg, uintptr_t value);
- uint32_t GetVReg(AbstractMethod** cur_quick_frame, const DexFile::CodeItem* code_item,
+ uint32_t GetVReg(mirror::AbstractMethod** cur_quick_frame, const DexFile::CodeItem* code_item,
uint32_t core_spills, uint32_t fp_spills, size_t frame_size,
uint16_t vreg) const {
int offset = GetVRegOffset(code_item, core_spills, fp_spills, frame_size, vreg);
@@ -471,7 +472,7 @@
return cur_quick_frame_pc_;
}
- AbstractMethod** GetCurrentQuickFrame() const {
+ mirror::AbstractMethod** GetCurrentQuickFrame() const {
return cur_quick_frame_;
}
@@ -480,7 +481,7 @@
}
StackIndirectReferenceTable* GetCurrentSirt() const {
- AbstractMethod** sp = GetCurrentQuickFrame();
+ mirror::AbstractMethod** sp = GetCurrentQuickFrame();
++sp; // Skip Method*; SIRT comes next;
return reinterpret_cast<StackIndirectReferenceTable*>(sp);
}
@@ -499,7 +500,7 @@
Thread* const thread_;
ShadowFrame* cur_shadow_frame_;
- AbstractMethod** cur_quick_frame_;
+ mirror::AbstractMethod** cur_quick_frame_;
uintptr_t cur_quick_frame_pc_;
// Lazily computed, number of frames in the stack.
size_t num_frames_;
diff --git a/src/stack_indirect_reference_table.h b/src/stack_indirect_reference_table.h
index 92fb003..dd10634 100644
--- a/src/stack_indirect_reference_table.h
+++ b/src/stack_indirect_reference_table.h
@@ -21,8 +21,9 @@
#include "base/macros.h"
namespace art {
-
+namespace mirror {
class Object;
+}
class Thread;
// Stack allocated indirect reference table. It can allocated within
@@ -30,7 +31,8 @@
// storage or manually allocated by SirtRef to hold one reference.
class StackIndirectReferenceTable {
public:
- explicit StackIndirectReferenceTable(Object* object) : number_of_references_(1), link_(NULL) {
+ explicit StackIndirectReferenceTable(mirror::Object* object) :
+ number_of_references_(1), link_(NULL) {
references_[0] = object;
}
@@ -51,17 +53,17 @@
link_ = sirt;
}
- Object* GetReference(size_t i) const {
+ mirror::Object* GetReference(size_t i) const {
DCHECK_LT(i, number_of_references_);
return references_[i];
}
- void SetReference(size_t i, Object* object) {
+ void SetReference(size_t i, mirror::Object* object) {
DCHECK_LT(i, number_of_references_);
references_[i] = object;
}
- bool Contains(Object** sirt_entry) const {
+ bool Contains(mirror::Object** sirt_entry) const {
// A SIRT should always contain something. One created by the
// jni_compiler should have a jobject/jclass as a native method is
// passed in a this pointer or a class
@@ -87,7 +89,7 @@
StackIndirectReferenceTable* link_;
// number_of_references_ are available if this is allocated and filled in by jni_compiler.
- Object* references_[1];
+ mirror::Object* references_[1];
DISALLOW_COPY_AND_ASSIGN(StackIndirectReferenceTable);
};
diff --git a/src/thread.cc b/src/thread.cc
index 46cba06..01d6072 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -30,16 +30,22 @@
#include "base/mutex.h"
#include "class_linker.h"
-#include "class_loader.h"
+#include "class_linker-inl.h"
#include "cutils/atomic.h"
#include "cutils/atomic-inline.h"
#include "debugger.h"
#include "gc_map.h"
+#include "gc/card_table-inl.h"
#include "heap.h"
#include "jni_internal.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/class-inl.h"
+#include "mirror/class_loader.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
+#include "mirror/stack_trace_element.h"
#include "monitor.h"
#include "oat/runtime/context.h"
-#include "object.h"
#include "object_utils.h"
#include "reflection.h"
#include "runtime.h"
@@ -139,20 +145,20 @@
// Copy peer into self, deleting global reference when done.
CHECK(self->jpeer_ != NULL);
- self->opeer_ = soa.Decode<Object*>(self->jpeer_);
+ self->opeer_ = soa.Decode<mirror::Object*>(self->jpeer_);
self->GetJniEnv()->DeleteGlobalRef(self->jpeer_);
self->jpeer_ = NULL;
{
- SirtRef<String> thread_name(self, self->GetThreadName(soa));
+ SirtRef<mirror::String> thread_name(self, self->GetThreadName(soa));
self->SetThreadName(thread_name->ToModifiedUtf8().c_str());
}
Dbg::PostThreadStart(self);
// Invoke the 'run' method of our java.lang.Thread.
- Object* receiver = self->opeer_;
+ mirror::Object* receiver = self->opeer_;
jmethodID mid = WellKnownClasses::java_lang_Thread_run;
- AbstractMethod* m =
+ mirror::AbstractMethod* m =
receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(soa.DecodeMethod(mid));
m->Invoke(self, receiver, NULL, NULL);
}
@@ -162,8 +168,9 @@
return NULL;
}
-Thread* Thread::FromManagedThread(const ScopedObjectAccessUnchecked& soa, Object* thread_peer) {
- Field* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_vmData);
+Thread* Thread::FromManagedThread(const ScopedObjectAccessUnchecked& soa,
+ mirror::Object* thread_peer) {
+ mirror::Field* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_vmData);
Thread* result = reinterpret_cast<Thread*>(static_cast<uintptr_t>(f->GetInt(thread_peer)));
// Sanity check that if we have a result it is either suspended or we hold the thread_list_lock_
// to stop it from going away.
@@ -177,7 +184,7 @@
}
Thread* Thread::FromManagedThread(const ScopedObjectAccessUnchecked& soa, jobject java_thread) {
- return FromManagedThread(soa, soa.Decode<Object*>(java_thread));
+ return FromManagedThread(soa, soa.Decode<mirror::Object*>(java_thread));
}
static size_t FixStackSize(size_t stack_size) {
@@ -391,7 +398,7 @@
}
{
ScopedObjectAccess soa(this);
- opeer_ = soa.Decode<Object*>(peer.get());
+ opeer_ = soa.Decode<mirror::Object*>(peer.get());
}
env->CallNonvirtualVoidMethod(peer.get(),
WellKnownClasses::java_lang_Thread,
@@ -405,7 +412,7 @@
reinterpret_cast<jint>(self));
ScopedObjectAccess soa(self);
- SirtRef<String> peer_thread_name(soa.Self(), GetThreadName(soa));
+ SirtRef<mirror::String> peer_thread_name(soa.Self(), GetThreadName(soa));
if (peer_thread_name.get() == NULL) {
// The Thread constructor should have set the Thread.name to a
// non-null value. However, because we can run without code
@@ -414,9 +421,9 @@
soa.DecodeField(WellKnownClasses::java_lang_Thread_daemon)->
SetBoolean(opeer_, thread_is_daemon);
soa.DecodeField(WellKnownClasses::java_lang_Thread_group)->
- SetObject(opeer_, soa.Decode<Object*>(thread_group));
+ SetObject(opeer_, soa.Decode<mirror::Object*>(thread_group));
soa.DecodeField(WellKnownClasses::java_lang_Thread_name)->
- SetObject(opeer_, soa.Decode<Object*>(thread_name.get()));
+ SetObject(opeer_, soa.Decode<mirror::Object*>(thread_name.get()));
soa.DecodeField(WellKnownClasses::java_lang_Thread_priority)->
SetInt(opeer_, thread_priority);
peer_thread_name.reset(GetThreadName(soa));
@@ -506,9 +513,9 @@
DumpStack(os);
}
-String* Thread::GetThreadName(const ScopedObjectAccessUnchecked& soa) const {
- Field* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_name);
- return (opeer_ != NULL) ? reinterpret_cast<String*>(f->GetObject(opeer_)) : NULL;
+mirror::String* Thread::GetThreadName(const ScopedObjectAccessUnchecked& soa) const {
+ mirror::Field* f = soa.DecodeField(WellKnownClasses::java_lang_Thread_name);
+ return (opeer_ != NULL) ? reinterpret_cast<mirror::String*>(f->GetObject(opeer_)) : NULL;
}
void Thread::GetThreadName(std::string& name) const {
@@ -748,12 +755,14 @@
priority = soa.DecodeField(WellKnownClasses::java_lang_Thread_priority)->GetInt(thread->opeer_);
is_daemon = soa.DecodeField(WellKnownClasses::java_lang_Thread_daemon)->GetBoolean(thread->opeer_);
- Object* thread_group =
+ mirror::Object* thread_group =
soa.DecodeField(WellKnownClasses::java_lang_Thread_group)->GetObject(thread->opeer_);
if (thread_group != NULL) {
- Field* group_name_field = soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_name);
- String* group_name_string = reinterpret_cast<String*>(group_name_field->GetObject(thread_group));
+ mirror::Field* group_name_field =
+ soa.DecodeField(WellKnownClasses::java_lang_ThreadGroup_name);
+ mirror::String* group_name_string =
+ reinterpret_cast<mirror::String*>(group_name_field->GetObject(thread_group));
group_name = (group_name_string != NULL) ? group_name_string->ToModifiedUtf8() : "<null>";
}
} else {
@@ -848,13 +857,13 @@
}
bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* m = GetMethod();
+ mirror::AbstractMethod* m = GetMethod();
if (m->IsRuntimeMethod()) {
return true;
}
const int kMaxRepetition = 3;
- Class* c = m->GetDeclaringClass();
- const DexCache* dex_cache = c->GetDexCache();
+ mirror::Class* c = m->GetDeclaringClass();
+ const mirror::DexCache* dex_cache = c->GetDexCache();
int line_number = -1;
if (dex_cache != NULL) { // be tolerant of bad input
const DexFile& dex_file = *dex_cache->GetDexFile();
@@ -893,7 +902,7 @@
return true;
}
- static void DumpLockedObject(Object* o, void* context)
+ static void DumpLockedObject(mirror::Object* o, void* context)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
std::ostream& os = *reinterpret_cast<std::ostream*>(context);
os << " - locked <" << o << "> (a " << PrettyTypeOf(o) << ")\n";
@@ -903,7 +912,7 @@
const Thread* thread;
bool can_allocate;
MethodHelper mh;
- AbstractMethod* last_method;
+ mirror::AbstractMethod* last_method;
int last_line_number;
int repetition_count;
int frame_count;
@@ -1016,14 +1025,14 @@
void Thread::AssertNoPendingException() const {
if (UNLIKELY(IsExceptionPending())) {
ScopedObjectAccess soa(Thread::Current());
- Throwable* exception = GetException();
+ mirror::Throwable* exception = GetException();
LOG(FATAL) << "No pending exception expected: " << exception->Dump();
}
}
-static void MonitorExitVisitor(const Object* object, void* arg) NO_THREAD_SAFETY_ANALYSIS {
+static void MonitorExitVisitor(const mirror::Object* object, void* arg) NO_THREAD_SAFETY_ANALYSIS {
Thread* self = reinterpret_cast<Thread*>(arg);
- Object* entered_monitor = const_cast<Object*>(object);
+ mirror::Object* entered_monitor = const_cast<mirror::Object*>(object);
if (self->HoldsLock(entered_monitor)) {
LOG(WARNING) << "Calling MonitorExit on object "
<< object << " (" << PrettyTypeOf(object) << ")"
@@ -1049,7 +1058,8 @@
// Thread.join() is implemented as an Object.wait() on the Thread.lock object. Signal anyone
// who is waiting.
- Object* lock = soa.DecodeField(WellKnownClasses::java_lang_Thread_lock)->GetObject(opeer_);
+ mirror::Object* lock =
+ soa.DecodeField(WellKnownClasses::java_lang_Thread_lock)->GetObject(opeer_);
// (This conditional is only needed for tests, where Thread.lock won't have been set.)
if (lock != NULL) {
lock->MonitorEnter(self);
@@ -1125,7 +1135,7 @@
void Thread::RemoveFromThreadGroup(ScopedObjectAccess& soa) {
// this.group.removeThread(this);
// group can be null if we're in the compiler or a test.
- Object* ogroup = soa.DecodeField(WellKnownClasses::java_lang_Thread_group)->GetObject(opeer_);
+ mirror::Object* ogroup = soa.DecodeField(WellKnownClasses::java_lang_Thread_group)->GetObject(opeer_);
if (ogroup != NULL) {
ScopedLocalRef<jobject> group(soa.Env(), soa.AddLocalReference<jobject>(ogroup));
ScopedLocalRef<jobject> peer(soa.Env(), soa.AddLocalReference<jobject>(opeer_));
@@ -1144,7 +1154,7 @@
}
bool Thread::SirtContains(jobject obj) const {
- Object** sirt_entry = reinterpret_cast<Object**>(obj);
+ mirror::Object** sirt_entry = reinterpret_cast<mirror::Object**>(obj);
for (StackIndirectReferenceTable* cur = top_sirt_; cur; cur = cur->GetLink()) {
if (cur->Contains(sirt_entry)) {
return true;
@@ -1154,11 +1164,11 @@
return managed_stack_.ShadowFramesContain(sirt_entry);
}
-void Thread::SirtVisitRoots(Heap::RootVisitor* visitor, void* arg) {
+void Thread::SirtVisitRoots(RootVisitor* visitor, void* arg) {
for (StackIndirectReferenceTable* cur = top_sirt_; cur; cur = cur->GetLink()) {
size_t num_refs = cur->NumberOfReferences();
for (size_t j = 0; j < num_refs; j++) {
- Object* object = cur->GetReference(j);
+ mirror::Object* object = cur->GetReference(j);
if (object != NULL) {
visitor(object, arg);
}
@@ -1166,19 +1176,19 @@
}
}
-Object* Thread::DecodeJObject(jobject obj) const {
+mirror::Object* Thread::DecodeJObject(jobject obj) const {
Locks::mutator_lock_->AssertSharedHeld(this);
if (obj == NULL) {
return NULL;
}
IndirectRef ref = reinterpret_cast<IndirectRef>(obj);
IndirectRefKind kind = GetIndirectRefKind(ref);
- Object* result;
+ mirror::Object* result;
switch (kind) {
case kLocal:
{
IndirectReferenceTable& locals = jni_env_->locals;
- result = const_cast<Object*>(locals.Get(ref));
+ result = const_cast<mirror::Object*>(locals.Get(ref));
break;
}
case kGlobal:
@@ -1186,7 +1196,7 @@
JavaVMExt* vm = Runtime::Current()->GetJavaVM();
IndirectReferenceTable& globals = vm->globals;
MutexLock mu(const_cast<Thread*>(this), vm->globals_lock);
- result = const_cast<Object*>(globals.Get(ref));
+ result = const_cast<mirror::Object*>(globals.Get(ref));
break;
}
case kWeakGlobal:
@@ -1194,7 +1204,7 @@
JavaVMExt* vm = Runtime::Current()->GetJavaVM();
IndirectReferenceTable& weak_globals = vm->weak_globals;
MutexLock mu(const_cast<Thread*>(this), vm->weak_globals_lock);
- result = const_cast<Object*>(weak_globals.Get(ref));
+ result = const_cast<mirror::Object*>(weak_globals.Get(ref));
if (result == kClearedJniWeakGlobal) {
// This is a special case where it's okay to return NULL.
return NULL;
@@ -1206,10 +1216,10 @@
// TODO: make stack indirect reference table lookup more efficient
// Check if this is a local reference in the SIRT
if (SirtContains(obj)) {
- result = *reinterpret_cast<Object**>(obj); // Read from SIRT
+ result = *reinterpret_cast<mirror::Object**>(obj); // Read from SIRT
} else if (Runtime::Current()->GetJavaVM()->work_around_app_jni_bugs) {
// Assume an invalid local reference is actually a direct pointer.
- result = reinterpret_cast<Object*>(obj);
+ result = reinterpret_cast<mirror::Object*>(obj);
} else {
result = kInvalidIndirectRefObject;
}
@@ -1272,9 +1282,9 @@
// We want to skip frames up to and including the exception's constructor.
// Note we also skip the frame if it doesn't have a method (namely the callee
// save frame)
- AbstractMethod* m = GetMethod();
+ mirror::AbstractMethod* m = GetMethod();
if (skipping_ && !m->IsRuntimeMethod() &&
- !Throwable::GetJavaLangThrowable()->IsAssignableFrom(m->GetDeclaringClass())) {
+ !mirror::Throwable::GetJavaLangThrowable()->IsAssignableFrom(m->GetDeclaringClass())) {
skipping_ = false;
}
if (!skipping_) {
@@ -1310,14 +1320,14 @@
bool Init(int depth)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Allocate method trace with an extra slot that will hold the PC trace
- SirtRef<ObjectArray<Object> >
+ SirtRef<mirror::ObjectArray<mirror::Object> >
method_trace(self_,
- Runtime::Current()->GetClassLinker()->AllocObjectArray<Object>(self_,
- depth + 1));
+ Runtime::Current()->GetClassLinker()->AllocObjectArray<mirror::Object>(self_,
+ depth + 1));
if (method_trace.get() == NULL) {
return false;
}
- IntArray* dex_pc_trace = IntArray::Alloc(self_, depth);
+ mirror::IntArray* dex_pc_trace = mirror::IntArray::Alloc(self_, depth);
if (dex_pc_trace == NULL) {
return false;
}
@@ -1347,7 +1357,7 @@
skip_depth_--;
return true;
}
- AbstractMethod* m = GetMethod();
+ mirror::AbstractMethod* m = GetMethod();
if (m->IsRuntimeMethod()) {
return true; // Ignore runtime frames (in particular callee save).
}
@@ -1357,7 +1367,7 @@
return true;
}
- ObjectArray<Object>* GetInternalStackTrace() const {
+ mirror::ObjectArray<mirror::Object>* GetInternalStackTrace() const {
return method_trace_;
}
@@ -1368,9 +1378,9 @@
// Current position down stack trace.
uint32_t count_;
// Array of dex PC values.
- IntArray* dex_pc_trace_;
+ mirror::IntArray* dex_pc_trace_;
// An array of the methods on the stack, the last entry is a reference to the PC trace.
- ObjectArray<Object>* method_trace_;
+ mirror::ObjectArray<mirror::Object>* method_trace_;
};
jobject Thread::CreateInternalStackTrace(const ScopedObjectAccessUnchecked& soa) const {
@@ -1387,7 +1397,7 @@
return NULL; // Allocation failed.
}
build_trace_visitor.WalkStack();
- ObjectArray<Object>* trace = build_trace_visitor.GetInternalStackTrace();
+ mirror::ObjectArray<mirror::Object>* trace = build_trace_visitor.GetInternalStackTrace();
if (kIsDebugBuild) {
for (int32_t i = 0; i < trace->GetLength(); ++i) {
CHECK(trace->Get(i) != NULL);
@@ -1401,18 +1411,19 @@
// Transition into runnable state to work on Object*/Array*
ScopedObjectAccess soa(env);
// Decode the internal stack trace into the depth, method trace and PC trace
- ObjectArray<Object>* method_trace = soa.Decode<ObjectArray<Object>*>(internal);
+ mirror::ObjectArray<mirror::Object>* method_trace =
+ soa.Decode<mirror::ObjectArray<mirror::Object>*>(internal);
int32_t depth = method_trace->GetLength() - 1;
- IntArray* pc_trace = down_cast<IntArray*>(method_trace->Get(depth));
+ mirror::IntArray* pc_trace = down_cast<mirror::IntArray*>(method_trace->Get(depth));
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
jobjectArray result;
- ObjectArray<StackTraceElement>* java_traces;
+ mirror::ObjectArray<mirror::StackTraceElement>* java_traces;
if (output_array != NULL) {
// Reuse the array we were given.
result = output_array;
- java_traces = soa.Decode<ObjectArray<StackTraceElement>*>(output_array);
+ java_traces = soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>*>(output_array);
// ...adjusting the number of frames we'll write to not exceed the array length.
depth = std::min(depth, java_traces->GetLength());
} else {
@@ -1431,7 +1442,7 @@
MethodHelper mh;
for (int32_t i = 0; i < depth; ++i) {
// Prepare parameters for StackTraceElement(String cls, String method, String file, int line)
- AbstractMethod* method = down_cast<AbstractMethod*>(method_trace->Get(i));
+ mirror::AbstractMethod* method = down_cast<mirror::AbstractMethod*>(method_trace->Get(i));
mh.ChangeMethod(method);
uint32_t dex_pc = pc_trace->Get(i);
int32_t line_number = mh.GetLineNumFromDexPC(dex_pc);
@@ -1440,27 +1451,28 @@
const char* descriptor = mh.GetDeclaringClassDescriptor();
CHECK(descriptor != NULL);
std::string class_name(PrettyDescriptor(descriptor));
- SirtRef<String> class_name_object(soa.Self(),
- String::AllocFromModifiedUtf8(soa.Self(),
- class_name.c_str()));
+ SirtRef<mirror::String> class_name_object(soa.Self(),
+ mirror::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(soa.Self(),
- method_name));
+ SirtRef<mirror::String> method_name_object(soa.Self(),
+ mirror::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(soa.Self(),
- source_file));
- StackTraceElement* obj = StackTraceElement::Alloc(soa.Self(),
- class_name_object.get(),
- method_name_object.get(),
- source_name_object.get(),
- line_number);
+ SirtRef<mirror::String> source_name_object(soa.Self(), mirror::String::AllocFromModifiedUtf8(soa.Self(),
+ source_file));
+ mirror::StackTraceElement* obj = mirror::StackTraceElement::Alloc(soa.Self(),
+ class_name_object.get(),
+ method_name_object.get(),
+ source_name_object.get(),
+ line_number);
if (obj == NULL) {
return NULL;
}
@@ -1520,10 +1532,11 @@
env, reinterpret_cast<jthrowable>(env->AllocObject(exception_class.get())));
if (exception.get() != NULL) {
ScopedObjectAccessUnchecked soa(env);
- Throwable* t = reinterpret_cast<Throwable*>(soa.Self()->DecodeJObject(exception.get()));
- t->SetDetailMessage(String::AllocFromModifiedUtf8(soa.Self(), msg));
+ mirror::Throwable* t =
+ reinterpret_cast<mirror::Throwable*>(soa.Self()->DecodeJObject(exception.get()));
+ t->SetDetailMessage(mirror::String::AllocFromModifiedUtf8(soa.Self(), msg));
if (cause != NULL) {
- t->SetCause(soa.Decode<Throwable*>(cause));
+ t->SetCause(soa.Decode<mirror::Throwable*>(cause));
}
soa.Self()->SetException(t);
} else {
@@ -1691,7 +1704,7 @@
static const bool kDebugExceptionDelivery = false;
class CatchBlockStackVisitor : public StackVisitor {
public:
- CatchBlockStackVisitor(Thread* self, Throwable* exception)
+ CatchBlockStackVisitor(Thread* self, mirror::Throwable* exception)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: StackVisitor(self, self->GetLongJumpContext()),
self_(self), exception_(exception), to_find_(exception->GetClass()), throw_method_(NULL),
@@ -1708,7 +1721,7 @@
bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* method = GetMethod();
+ mirror::AbstractMethod* method = GetMethod();
if (method == NULL) {
// This is the upcall, we remember the frame and last pc so that we may long jump to them.
handler_quick_frame_pc_ = GetCurrentQuickFramePc();
@@ -1751,7 +1764,7 @@
}
void DoLongJump() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* catch_method = *handler_quick_frame_;
+ mirror::AbstractMethod* catch_method = *handler_quick_frame_;
if (kDebugExceptionDelivery) {
if (catch_method == NULL) {
LOG(INFO) << "Handler is upcall";
@@ -1777,14 +1790,14 @@
private:
Thread* self_;
- Throwable* exception_;
+ mirror::Throwable* exception_;
// The type of the exception catch block to find.
- Class* to_find_;
- AbstractMethod* throw_method_;
+ mirror::Class* to_find_;
+ mirror::AbstractMethod* throw_method_;
JDWP::FrameId throw_frame_id_;
uint32_t throw_dex_pc_;
// Quick frame with found handler or last frame if no handler found.
- AbstractMethod** handler_quick_frame_;
+ mirror::AbstractMethod** handler_quick_frame_;
// PC to branch to for the handler.
uintptr_t handler_quick_frame_pc_;
// Associated dex PC.
@@ -1798,13 +1811,13 @@
};
void Thread::QuickDeliverException() {
- Throwable* exception = GetException(); // Get exception from thread
+ mirror::Throwable* exception = GetException(); // Get exception from thread
CHECK(exception != NULL);
// Don't leave exception visible while we try to find the handler, which may cause class
// resolution.
ClearException();
if (kDebugExceptionDelivery) {
- String* msg = exception->GetDetailMessage();
+ mirror::String* msg = exception->GetDetailMessage();
std::string str_msg(msg != NULL ? msg->ToModifiedUtf8() : "");
DumpStack(LOG(INFO) << "Delivering exception: " << PrettyTypeOf(exception)
<< ": " << str_msg << "\n");
@@ -1826,14 +1839,14 @@
return result;
}
-AbstractMethod* Thread::GetCurrentMethod(uint32_t* dex_pc, size_t* frame_id) const {
+mirror::AbstractMethod* Thread::GetCurrentMethod(uint32_t* dex_pc, size_t* frame_id) const {
struct CurrentMethodVisitor : public StackVisitor {
CurrentMethodVisitor(Thread* thread)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: StackVisitor(thread, NULL), method_(NULL), dex_pc_(0), frame_id_(0) {}
virtual bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* m = GetMethod();
+ mirror::AbstractMethod* m = GetMethod();
if (m->IsRuntimeMethod()) {
// Continue if this is a runtime method.
return true;
@@ -1843,7 +1856,7 @@
frame_id_ = GetFrameId();
return false;
}
- AbstractMethod* method_;
+ mirror::AbstractMethod* method_;
uint32_t dex_pc_;
size_t frame_id_;
};
@@ -1859,7 +1872,7 @@
return visitor.method_;
}
-bool Thread::HoldsLock(Object* object) {
+bool Thread::HoldsLock(mirror::Object* object) {
if (object == NULL) {
return false;
}
@@ -1881,12 +1894,12 @@
}
ShadowFrame* shadow_frame = GetCurrentShadowFrame();
if (shadow_frame != NULL) {
- AbstractMethod* m = shadow_frame->GetMethod();
+ mirror::AbstractMethod* m = shadow_frame->GetMethod();
size_t num_regs = shadow_frame->NumberOfVRegs();
if (m->IsNative() || shadow_frame->HasReferenceArray()) {
// SIRT for JNI or References for interpreter.
for (size_t reg = 0; reg < num_regs; ++reg) {
- Object* ref = shadow_frame->GetVRegReference(reg);
+ mirror::Object* ref = shadow_frame->GetVRegReference(reg);
if (ref != NULL) {
visitor_(ref, reg, this);
}
@@ -1907,7 +1920,7 @@
num_regs = std::min(dex_gc_map.RegWidth() * 8, num_regs);
for (size_t reg = 0; reg < num_regs; ++reg) {
if (TestBitmap(reg, reg_bitmap)) {
- Object* ref = shadow_frame->GetVRegReference(reg);
+ mirror::Object* ref = shadow_frame->GetVRegReference(reg);
if (ref != NULL) {
visitor_(ref, reg, this);
}
@@ -1915,7 +1928,7 @@
}
}
} else {
- AbstractMethod* m = GetMethod();
+ mirror::AbstractMethod* m = GetMethod();
// Process register map (which native and runtime methods don't have)
if (!m->IsNative() && !m->IsRuntimeMethod() && !m->IsProxyMethod()) {
const uint8_t* native_gc_map = m->GetNativeGcMap();
@@ -1934,20 +1947,21 @@
uint32_t fp_spills = m->GetFpSpillMask();
size_t frame_size = m->GetFrameSizeInBytes();
// For all dex registers in the bitmap
- AbstractMethod** cur_quick_frame = GetCurrentQuickFrame();
+ mirror::AbstractMethod** cur_quick_frame = GetCurrentQuickFrame();
DCHECK(cur_quick_frame != NULL);
for (size_t reg = 0; reg < num_regs; ++reg) {
// Does this register hold a reference?
if (TestBitmap(reg, reg_bitmap)) {
uint32_t vmap_offset;
- Object* ref;
+ mirror::Object* ref;
if (vmap_table.IsInContext(reg, vmap_offset, kReferenceVReg)) {
uintptr_t val = GetGPR(vmap_table.ComputeRegister(core_spills, vmap_offset,
kReferenceVReg));
- ref = reinterpret_cast<Object*>(val);
+ ref = reinterpret_cast<mirror::Object*>(val);
} else {
- ref = reinterpret_cast<Object*>(GetVReg(cur_quick_frame, code_item, core_spills,
- fp_spills, frame_size, reg));
+ ref = reinterpret_cast<mirror::Object*>(GetVReg(cur_quick_frame, code_item,
+ core_spills, fp_spills, frame_size,
+ reg));
}
if (ref != NULL) {
@@ -1975,46 +1989,46 @@
class RootCallbackVisitor {
public:
- RootCallbackVisitor(Heap::RootVisitor* visitor, void* arg) : visitor_(visitor), arg_(arg) {
+ RootCallbackVisitor(RootVisitor* visitor, void* arg) : visitor_(visitor), arg_(arg) {
}
- void operator()(const Object* obj, size_t, const StackVisitor*) const {
+ void operator()(const mirror::Object* obj, size_t, const StackVisitor*) const {
visitor_(obj, arg_);
}
private:
- Heap::RootVisitor* visitor_;
+ RootVisitor* visitor_;
void* arg_;
};
class VerifyCallbackVisitor {
public:
- VerifyCallbackVisitor(Heap::VerifyRootVisitor* visitor, void* arg)
+ VerifyCallbackVisitor(VerifyRootVisitor* visitor, void* arg)
: visitor_(visitor),
arg_(arg) {
}
- void operator()(const Object* obj, size_t vreg, const StackVisitor* visitor) const {
+ void operator()(const mirror::Object* obj, size_t vreg, const StackVisitor* visitor) const {
visitor_(obj, arg_, vreg, visitor);
}
private:
- Heap::VerifyRootVisitor* const visitor_;
+ VerifyRootVisitor* const visitor_;
void* const arg_;
};
struct VerifyRootWrapperArg {
- Heap::VerifyRootVisitor* visitor;
+ VerifyRootVisitor* visitor;
void* arg;
};
-static void VerifyRootWrapperCallback(const Object* root, void* arg) {
+static void VerifyRootWrapperCallback(const mirror::Object* root, void* arg) {
VerifyRootWrapperArg* wrapperArg = reinterpret_cast<VerifyRootWrapperArg*>(arg);
wrapperArg->visitor(root, wrapperArg->arg, 0, NULL);
}
-void Thread::VerifyRoots(Heap::VerifyRootVisitor* visitor, void* arg) {
+void Thread::VerifyRoots(VerifyRootVisitor* visitor, void* arg) {
// We need to map from a RootVisitor to VerifyRootVisitor, so pass in nulls for arguments we
// don't have.
VerifyRootWrapperArg wrapperArg;
@@ -2043,7 +2057,7 @@
ReleaseLongJumpContext(context);
}
-void Thread::VisitRoots(Heap::RootVisitor* visitor, void* arg) {
+void Thread::VisitRoots(RootVisitor* visitor, void* arg) {
if (opeer_ != NULL) {
visitor(opeer_, arg);
}
diff --git a/src/thread.h b/src/thread.h
index 13e1cab..c63fddf 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -31,19 +31,30 @@
#include "oat/runtime/oat_support_entrypoints.h"
#include "locks.h"
#include "offsets.h"
+#include "root_visitor.h"
#include "runtime_stats.h"
#include "stack.h"
#include "stack_indirect_reference_table.h"
+#include "thread_state.h"
#include "UniquePtr.h"
namespace art {
+namespace mirror {
class AbstractMethod;
class Array;
-class BaseMutex;
class Class;
-class ClassLinker;
class ClassLoader;
+class Object;
+template<class T> class ObjectArray;
+template<class T> class PrimitiveArray;
+typedef PrimitiveArray<int32_t> IntArray;
+class StackTraceElement;
+class StaticStorageBase;
+class Throwable;
+} // namespace mirror
+class BaseMutex;
+class ClassLinker;
class Closure;
class Context;
struct DebugInvokeReq;
@@ -51,20 +62,12 @@
struct JavaVMExt;
struct JNIEnvExt;
class Monitor;
-class Object;
class Runtime;
class ScopedObjectAccess;
class ScopedObjectAccessUnchecked;
class ShadowFrame;
-class StackTraceElement;
-class StaticStorageBase;
class Thread;
class ThreadList;
-class Throwable;
-
-template<class T> class ObjectArray;
-template<class T> class PrimitiveArray;
-typedef PrimitiveArray<int32_t> IntArray;
// Thread priorities. These must match the Thread.MIN_PRIORITY,
// Thread.NORM_PRIORITY, and Thread.MAX_PRIORITY constants.
@@ -74,28 +77,6 @@
kMaxThreadPriority = 10,
};
-enum ThreadState {
- // Thread.State JDWP state
- kTerminated, // TERMINATED TS_ZOMBIE Thread.run has returned, but Thread* still around
- kRunnable, // RUNNABLE TS_RUNNING runnable
- kTimedWaiting, // TIMED_WAITING TS_WAIT in Object.wait() with a timeout
- kSleeping, // TIMED_WAITING TS_SLEEPING in Thread.sleep()
- kBlocked, // BLOCKED TS_MONITOR blocked on a monitor
- kWaiting, // WAITING TS_WAIT in Object.wait()
- kWaitingForGcToComplete, // WAITING TS_WAIT blocked waiting for GC
- kWaitingPerformingGc, // WAITING TS_WAIT performing GC
- kWaitingForDebuggerSend, // WAITING TS_WAIT blocked waiting for events to be sent
- kWaitingForDebuggerToAttach, // WAITING TS_WAIT blocked waiting for debugger to attach
- kWaitingInMainDebuggerLoop, // WAITING TS_WAIT blocking/reading/processing debugger events
- kWaitingForDebuggerSuspension, // WAITING TS_WAIT waiting for debugger suspend all
- kWaitingForJniOnLoad, // WAITING TS_WAIT waiting for execution of dlopen and JNI on load code
- kWaitingForSignalCatcherOutput, // WAITING TS_WAIT waiting for signal catcher IO to complete
- kWaitingInMainSignalCatcherLoop, // WAITING TS_WAIT blocking/reading/processing signals
- kStarting, // NEW TS_WAIT native thread started, not yet ready to run managed code
- kNative, // RUNNABLE TS_RUNNING running in a JNI native method
- kSuspended, // RUNNABLE TS_RUNNING suspended by GC or debugger
-};
-
enum ThreadFlag {
kSuspendRequest = 1, // If set implies that suspend_count_ > 0 and the Thread should enter the
// safepoint handler.
@@ -127,7 +108,8 @@
return reinterpret_cast<Thread*>(thread);
}
- static Thread* FromManagedThread(const ScopedObjectAccessUnchecked& ts, Object* thread_peer)
+ static Thread* FromManagedThread(const ScopedObjectAccessUnchecked& ts,
+ mirror::Object* thread_peer)
EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_)
LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -245,7 +227,7 @@
return daemon_;
}
- bool HoldsLock(Object*);
+ bool HoldsLock(mirror::Object*);
/*
* Changes the priority of this thread to match that of the java.lang.Thread object.
@@ -272,7 +254,7 @@
}
// Returns the java.lang.Thread's name, or NULL if this Thread* doesn't have a peer.
- String* GetThreadName(const ScopedObjectAccessUnchecked& ts) const
+ mirror::String* GetThreadName(const ScopedObjectAccessUnchecked& ts) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Sets 'name' to the java.lang.Thread's name. This requires no transition to managed code,
@@ -282,7 +264,7 @@
// Sets the thread's name.
void SetThreadName(const char* name) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- Object* GetPeer() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ mirror::Object* GetPeer() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK(jpeer_ == NULL);
return opeer_;
}
@@ -301,13 +283,13 @@
return exception_ != NULL;
}
- Throwable* GetException() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ mirror::Throwable* GetException() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return exception_;
}
void AssertNoPendingException() const;
- void SetException(Throwable* new_exception) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ void SetException(mirror::Throwable* new_exception) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
CHECK(new_exception != NULL);
// TODO: DCHECK(!IsExceptionPending());
exception_ = new_exception;
@@ -317,7 +299,7 @@
exception_ = NULL;
}
- void DeliverException(Throwable* exception) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ void DeliverException(mirror::Throwable* exception) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
if (exception == NULL) {
ThrowNewException("Ljava/lang/NullPointerException;", "throw with null exception");
} else {
@@ -334,11 +316,11 @@
long_jump_context_ = context;
}
- AbstractMethod* GetCurrentMethod(uint32_t* dex_pc = NULL, size_t* frame_id = NULL) const
+ mirror::AbstractMethod* GetCurrentMethod(uint32_t* dex_pc = NULL, size_t* frame_id = NULL) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void SetTopOfStack(void* stack, uintptr_t pc) {
- AbstractMethod** top_method = reinterpret_cast<AbstractMethod**>(stack);
+ mirror::AbstractMethod** top_method = reinterpret_cast<mirror::AbstractMethod**>(stack);
managed_stack_.SetTopQuickFrame(top_method);
managed_stack_.SetTopQuickFramePc(pc);
}
@@ -369,7 +351,7 @@
//QuickFrameIterator FindExceptionHandler(void* throw_pc, void** handler_pc);
- void* FindExceptionHandlerInMethod(const AbstractMethod* method,
+ void* FindExceptionHandlerInMethod(const mirror::AbstractMethod* method,
void* throw_pc,
const DexFile& dex_file,
ClassLinker* class_linker);
@@ -384,7 +366,7 @@
}
// Convert a jobject into a Object*
- Object* DecodeJObject(jobject obj) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::Object* DecodeJObject(jobject obj) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Implements java.lang.Thread.interrupted.
bool Interrupted();
@@ -393,11 +375,11 @@
void Interrupt();
void Notify();
- ClassLoader* GetClassLoaderOverride() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ mirror::ClassLoader* GetClassLoaderOverride() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return class_loader_override_;
}
- void SetClassLoaderOverride(ClassLoader* class_loader_override) {
+ void SetClassLoaderOverride(mirror::ClassLoader* class_loader_override) {
class_loader_override_ = class_loader_override;
}
@@ -413,10 +395,10 @@
static jobjectArray InternalStackTraceToStackTraceElementArray(JNIEnv* env, jobject internal,
jobjectArray output_array = NULL, int* stack_depth = NULL);
- void VisitRoots(Heap::RootVisitor* visitor, void* arg)
+ void VisitRoots(RootVisitor* visitor, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void VerifyRoots(Heap::VerifyRootVisitor* visitor, void* arg)
+ void VerifyRoots(VerifyRootVisitor* visitor, void* arg)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
#if VERIFY_OBJECT_ENABLED
@@ -535,7 +517,7 @@
// Is the given obj in this thread's stack indirect reference table?
bool SirtContains(jobject obj) const;
- void SirtVisitRoots(Heap::RootVisitor* visitor, void* arg);
+ void SirtVisitRoots(RootVisitor* visitor, void* arg);
void PushSirt(StackIndirectReferenceTable* sirt) {
sirt->SetLink(top_sirt_);
@@ -692,7 +674,7 @@
byte* card_table_;
// The pending exception or NULL.
- Throwable* exception_;
+ mirror::Throwable* exception_;
// The end of this thread's stack. This is the lowest safely-addressable address on the stack.
// We leave extra space so there's room for the code that throws StackOverflowError.
@@ -711,7 +693,7 @@
// Our managed peer (an instance of java.lang.Thread). The jobject version is used during thread
// start up, until the thread is registered and the local opeer_ is used.
- Object* opeer_;
+ mirror::Object* opeer_;
jobject jpeer_;
// The "lowest addressable byte" of the stack
@@ -740,7 +722,7 @@
// The next thread in the wait set this thread is part of.
Thread* wait_next_;
// If we're blocked in MonitorEnter, this is the object we're trying to lock.
- Object* monitor_enter_object_;
+ mirror::Object* monitor_enter_object_;
friend class Monitor;
friend class MonitorInfo;
@@ -754,7 +736,7 @@
// Needed to get the right ClassLoader in JNI_OnLoad, but also
// useful for testing.
- ClassLoader* class_loader_override_;
+ mirror::ClassLoader* class_loader_override_;
// Thread local, lazily allocated, long jump context. Used to deliver exceptions.
Context* long_jump_context_;
diff --git a/src/thread_list.cc b/src/thread_list.cc
index 13c965c..ea8baac 100644
--- a/src/thread_list.cc
+++ b/src/thread_list.cc
@@ -22,6 +22,7 @@
#include "base/mutex.h"
#include "debugger.h"
+#include "thread.h"
#include "timing_logger.h"
#include "utils.h"
@@ -579,14 +580,14 @@
}
}
-void ThreadList::VisitRoots(Heap::RootVisitor* visitor, void* arg) const {
+void ThreadList::VisitRoots(RootVisitor* visitor, void* arg) const {
MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
(*it)->VisitRoots(visitor, arg);
}
}
-void ThreadList::VerifyRoots(Heap::VerifyRootVisitor* visitor, void* arg) const {
+void ThreadList::VerifyRoots(VerifyRootVisitor* visitor, void* arg) const {
MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
(*it)->VerifyRoots(visitor, arg);
diff --git a/src/thread_list.h b/src/thread_list.h
index 7ded5e3..0470cfc 100644
--- a/src/thread_list.h
+++ b/src/thread_list.h
@@ -18,10 +18,14 @@
#define ART_SRC_THREAD_LIST_H_
#include "base/mutex.h"
-#include "thread.h"
+#include "root_visitor.h"
+
+#include <bitset>
+#include <list>
namespace art {
-
+class Closure;
+class Thread;
class TimingLogger;
class ThreadList {
@@ -84,10 +88,10 @@
LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_);
void Unregister(Thread* self) LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_);
- void VisitRoots(Heap::RootVisitor* visitor, void* arg) const
+ void VisitRoots(RootVisitor* visitor, void* arg) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- void VerifyRoots(Heap::VerifyRootVisitor* visitor, void* arg) const
+ void VerifyRoots(VerifyRootVisitor* visitor, void* arg) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Return a copy of the thread list.
diff --git a/src/thread_state.h b/src/thread_state.h
new file mode 100644
index 0000000..7c4a16f
--- /dev/null
+++ b/src/thread_state.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_THREAD_STATE_H_
+#define ART_SRC_THREAD_STATE_H_
+
+namespace art {
+
+enum ThreadState {
+ // Thread.State JDWP state
+ kTerminated, // TERMINATED TS_ZOMBIE Thread.run has returned, but Thread* still around
+ kRunnable, // RUNNABLE TS_RUNNING runnable
+ kTimedWaiting, // TIMED_WAITING TS_WAIT in Object.wait() with a timeout
+ kSleeping, // TIMED_WAITING TS_SLEEPING in Thread.sleep()
+ kBlocked, // BLOCKED TS_MONITOR blocked on a monitor
+ kWaiting, // WAITING TS_WAIT in Object.wait()
+ kWaitingForGcToComplete, // WAITING TS_WAIT blocked waiting for GC
+ kWaitingPerformingGc, // WAITING TS_WAIT performing GC
+ kWaitingForDebuggerSend, // WAITING TS_WAIT blocked waiting for events to be sent
+ kWaitingForDebuggerToAttach, // WAITING TS_WAIT blocked waiting for debugger to attach
+ kWaitingInMainDebuggerLoop, // WAITING TS_WAIT blocking/reading/processing debugger events
+ kWaitingForDebuggerSuspension, // WAITING TS_WAIT waiting for debugger suspend all
+ kWaitingForJniOnLoad, // WAITING TS_WAIT waiting for execution of dlopen and JNI on load code
+ kWaitingForSignalCatcherOutput, // WAITING TS_WAIT waiting for signal catcher IO to complete
+ kWaitingInMainSignalCatcherLoop, // WAITING TS_WAIT blocking/reading/processing signals
+ kStarting, // NEW TS_WAIT native thread started, not yet ready to run managed code
+ kNative, // RUNNABLE TS_RUNNING running in a JNI native method
+ kSuspended, // RUNNABLE TS_RUNNING suspended by GC or debugger
+};
+
+} // namespace art
+
+#endif // ART_SRC_THREAD_STATE_H_
diff --git a/src/timing_logger.cc b/src/timing_logger.cc
new file mode 100644
index 0000000..fee7a30
--- /dev/null
+++ b/src/timing_logger.cc
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "timing_logger.h"
+
+#include "base/logging.h"
+#include "utils.h"
+
+#include <cmath>
+#include <iomanip>
+
+namespace art {
+
+void TimingLogger::Dump() const {
+ Dump(LOG(INFO));
+}
+
+void TimingLogger::Dump(std::ostream& os) const {
+ uint64_t largest_time = 0;
+ os << name_ << ": begin\n";
+ for (size_t i = 1; i < times_.size(); ++i) {
+ uint64_t delta_time = times_[i] - times_[i - 1];
+ largest_time = std::max(largest_time, delta_time);
+ }
+ // Compute which type of unit we will use for printing the timings.
+ TimeUnit tu = GetAppropriateTimeUnit(largest_time);
+ uint64_t divisor = GetNsToTimeUnitDivisor(tu);
+ for (size_t i = 1; i < times_.size(); ++i) {
+ uint64_t delta_time = times_[i] - times_[i - 1];
+ if (!precise_ && divisor >= 1000) {
+ // Make the fraction 0.
+ delta_time -= delta_time % (divisor / 1000);
+ }
+ os << name_ << ": " << std::setw(8) << FormatDuration(delta_time, tu) << " " << labels_[i]
+ << "\n";
+ }
+ os << name_ << ": end, " << NsToMs(GetTotalNs()) << " ms\n";
+}
+
+void CumulativeLogger::Dump() const {
+ Dump(LOG(INFO));
+}
+
+void CumulativeLogger::Dump(std::ostream& os) const {
+ os << name_ << ": iterations " << iterations_ << " begin\n";
+ //Find which unit we will use for the timing logger.
+ uint64_t largest_mean = 0;
+ for (size_t i = 0; i < times_.size(); ++i) {
+ // Convert back to nanoseconds from microseconds.
+ uint64_t mean = times_[i] / iterations_;
+ largest_mean = std::max(largest_mean, mean);
+ }
+ // Convert largest mean back to ns
+ TimeUnit tu = GetAppropriateTimeUnit(largest_mean * kAdjust);
+ uint64_t divisor = GetNsToTimeUnitDivisor(tu);
+ for (size_t i = 0; i < times_.size(); ++i) {
+ uint64_t mean_x2 = times_squared_[i] / iterations_;
+ uint64_t mean = times_[i] / iterations_;
+ uint64_t variance = mean_x2 - (mean * mean);
+ uint64_t std_dev = static_cast<uint64_t>(std::sqrt(static_cast<double>(variance)));
+ if (!precise_ && divisor >= 1000) {
+ // Make the fraction 0.
+ mean -= mean % (divisor / 1000);
+ std_dev -= std_dev % (divisor / 1000);
+ }
+ os << StringPrintf("%s: %10s (std_dev %8s) %s\n",
+ name_.c_str(),
+ FormatDuration(mean * kAdjust, tu).c_str(),
+ FormatDuration(std_dev * kAdjust, tu).c_str(),
+ labels_[i].c_str());
+ }
+ uint64_t total_mean_x2 = total_time_squared_;
+ uint64_t mean_total_ns = GetTotalTime();
+ if (iterations_ != 0) {
+ total_mean_x2 /= iterations_;
+ mean_total_ns /= iterations_;
+ }
+ uint64_t total_variance = total_mean_x2 - (mean_total_ns * mean_total_ns);
+ uint64_t total_std_dev = static_cast<uint64_t>(
+ std::sqrt(static_cast<double>(total_variance)));
+ os << name_ << ": end, mean " << PrettyDuration(mean_total_ns * kAdjust)
+ << " std_dev " << PrettyDuration(total_std_dev * kAdjust) << "\n";
+}
+
+} // namespace art
diff --git a/src/timing_logger.h b/src/timing_logger.h
index 3b3dcfc..fc47028 100644
--- a/src/timing_logger.h
+++ b/src/timing_logger.h
@@ -17,10 +17,8 @@
#ifndef ART_SRC_TIMING_LOGGER_H_
#define ART_SRC_TIMING_LOGGER_H_
-#include "base/logging.h"
-#include "utils.h"
+#include "utils.h" // For NanoTime.
-#include <cmath>
#include <stdint.h>
#include <string>
#include <vector>
@@ -47,31 +45,9 @@
labels_.push_back(label);
}
- void Dump() const {
- Dump(LOG(INFO));
- }
+ void Dump() const;
- void Dump(std::ostream& os) const {
- uint64_t largest_time = 0;
- os << name_ << ": begin\n";
- for (size_t i = 1; i < times_.size(); ++i) {
- uint64_t delta_time = times_[i] - times_[i - 1];
- largest_time = std::max(largest_time, delta_time);
- }
- // Compute which type of unit we will use for printing the timings.
- TimeUnit tu = GetAppropriateTimeUnit(largest_time);
- uint64_t divisor = GetNsToTimeUnitDivisor(tu);
- for (size_t i = 1; i < times_.size(); ++i) {
- uint64_t delta_time = times_[i] - times_[i - 1];
- if (!precise_ && divisor >= 1000) {
- // Make the fraction 0.
- delta_time -= delta_time % (divisor / 1000);
- }
- os << name_ << ": " << std::setw(8) << FormatDuration(delta_time, tu) << " " << labels_[i]
- << "\n";
- }
- os << name_ << ": end, " << NsToMs(GetTotalNs()) << " ms\n";
- }
+ void Dump(std::ostream& os) const;
uint64_t GetTotalNs() const {
return times_.back() - times_.front();
@@ -149,50 +125,9 @@
total_time_squared_ += total_time * total_time;
}
- void Dump() const {
- Dump(LOG(INFO));
- }
+ void Dump() const;
- void Dump(std::ostream& os) const {
- os << name_ << ": iterations " << iterations_ << " begin\n";
- //Find which unit we will use for the timing logger.
- uint64_t largest_mean = 0;
- for (size_t i = 0; i < times_.size(); ++i) {
- // Convert back to nanoseconds from microseconds.
- uint64_t mean = times_[i] / iterations_;
- largest_mean = std::max(largest_mean, mean);
- }
- // Convert largest mean back to ns
- TimeUnit tu = GetAppropriateTimeUnit(largest_mean * kAdjust);
- uint64_t divisor = GetNsToTimeUnitDivisor(tu);
- for (size_t i = 0; i < times_.size(); ++i) {
- uint64_t mean_x2 = times_squared_[i] / iterations_;
- uint64_t mean = times_[i] / iterations_;
- uint64_t variance = mean_x2 - (mean * mean);
- uint64_t std_dev = static_cast<uint64_t>(std::sqrt(static_cast<double>(variance)));
- if (!precise_ && divisor >= 1000) {
- // Make the fraction 0.
- mean -= mean % (divisor / 1000);
- std_dev -= std_dev % (divisor / 1000);
- }
- os << StringPrintf("%s: %10s (std_dev %8s) %s\n",
- name_.c_str(),
- FormatDuration(mean * kAdjust, tu).c_str(),
- FormatDuration(std_dev * kAdjust, tu).c_str(),
- labels_[i].c_str());
- }
- uint64_t total_mean_x2 = total_time_squared_;
- uint64_t mean_total_ns = GetTotalTime();
- if (iterations_ != 0) {
- total_mean_x2 /= iterations_;
- mean_total_ns /= iterations_;
- }
- uint64_t total_variance = total_mean_x2 - (mean_total_ns * mean_total_ns);
- uint64_t total_std_dev = static_cast<uint64_t>(
- std::sqrt(static_cast<double>(total_variance)));
- os << name_ << ": end, mean " << PrettyDuration(mean_total_ns * kAdjust)
- << " std_dev " << PrettyDuration(total_std_dev * kAdjust) << "\n";
- }
+ void Dump(std::ostream& os) const;
uint64_t GetTotalNs() const {
return GetTotalTime() * kAdjust;
diff --git a/src/trace.cc b/src/trace.cc
index 7b3cea8..a23d202 100644
--- a/src/trace.cc
+++ b/src/trace.cc
@@ -21,8 +21,10 @@
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
#include "debugger.h"
-#include "dex_cache.h"
#include "instrumentation.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/dex_cache.h"
+#include "mirror/object_array-inl.h"
#if !defined(ART_USE_LLVM_COMPILER)
#include "oat/runtime/oat_support_entrypoints.h"
#endif
@@ -322,7 +324,8 @@
}
}
-void Trace::LogMethodTraceEvent(Thread* self, const AbstractMethod* method, Trace::TraceEvent event) {
+void Trace::LogMethodTraceEvent(Thread* self, const mirror::AbstractMethod* method,
+ Trace::TraceEvent event) {
if (thread_clock_base_map_.find(self) == thread_clock_base_map_.end()) {
uint64_t time = ThreadCpuMicroTime();
thread_clock_base_map_.Put(self, time);
@@ -367,16 +370,17 @@
while (ptr < end) {
uint32_t method_value = ptr[2] | (ptr[3] << 8) | (ptr[4] << 16) | (ptr[5] << 24);
- AbstractMethod* method = reinterpret_cast<AbstractMethod*>(TraceMethodId(method_value));
+ mirror::AbstractMethod* method =
+ reinterpret_cast<mirror::AbstractMethod*>(TraceMethodId(method_value));
visited_methods_.insert(method);
ptr += record_size_;
}
}
void Trace::DumpMethodList(std::ostream& os) {
- typedef std::set<const AbstractMethod*>::const_iterator It; // TODO: C++0x auto
+ typedef std::set<const mirror::AbstractMethod*>::const_iterator It; // TODO: C++0x auto
for (It it = visited_methods_.begin(); it != visited_methods_.end(); ++it) {
- const AbstractMethod* method = *it;
+ const mirror::AbstractMethod* method = *it;
MethodHelper mh(method);
os << StringPrintf("%p\t%s\t%s\t%s\t%s\n", method,
PrettyDescriptor(mh.GetDeclaringClassDescriptor()).c_str(), mh.GetName(),
diff --git a/src/trace.h b/src/trace.h
index e3f254e..1be1cc4 100644
--- a/src/trace.h
+++ b/src/trace.h
@@ -29,7 +29,9 @@
namespace art {
+namespace mirror {
class AbstractMethod;
+} // namespace mirror
class Thread;
enum ProfilerClockSource {
@@ -59,7 +61,7 @@
bool UseWallClock();
bool UseThreadCpuClock();
- void LogMethodTraceEvent(Thread* self, const AbstractMethod* method, TraceEvent event);
+ void LogMethodTraceEvent(Thread* self, const mirror::AbstractMethod* method, TraceEvent event);
private:
explicit Trace(File* trace_file, int buffer_size, int flags);
@@ -73,7 +75,7 @@
void DumpThreadList(std::ostream& os) LOCKS_EXCLUDED(Locks::thread_list_lock_);
// Set of methods visited by the profiler.
- std::set<const AbstractMethod*> visited_methods_;
+ std::set<const mirror::AbstractMethod*> visited_methods_;
// Maps a thread to its clock base.
SafeMap<Thread*, uint64_t> thread_clock_base_map_;
diff --git a/src/utf.cc b/src/utf.cc
index 174fe22..cc7e262 100644
--- a/src/utf.cc
+++ b/src/utf.cc
@@ -17,7 +17,7 @@
#include "utf.h"
#include "base/logging.h"
-#include "object.h"
+#include "mirror/array.h"
namespace art {
@@ -66,7 +66,7 @@
}
}
-int32_t ComputeUtf16Hash(const CharArray* chars, int32_t offset,
+int32_t ComputeUtf16Hash(const mirror::CharArray* chars, int32_t offset,
size_t char_count) {
int32_t hash = 0;
for (size_t i = 0; i < char_count; i++) {
diff --git a/src/utf.h b/src/utf.h
index e95289e..44899bf 100644
--- a/src/utf.h
+++ b/src/utf.h
@@ -29,9 +29,10 @@
* See http://en.wikipedia.org/wiki/UTF-8#Modified_UTF-8 for the details.
*/
namespace art {
-
+namespace mirror {
template<class T> class PrimitiveArray;
typedef PrimitiveArray<uint16_t> CharArray;
+} // namespace mirror
/*
* Returns the number of UTF-16 characters in the given modified UTF-8 string.
@@ -65,7 +66,7 @@
/*
* The java.lang.String hashCode() algorithm.
*/
-int32_t ComputeUtf16Hash(const CharArray* chars, int32_t offset, size_t char_count)
+int32_t ComputeUtf16Hash(const mirror::CharArray* chars, int32_t offset, size_t char_count)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
int32_t ComputeUtf16Hash(const uint16_t* chars, size_t char_count);
diff --git a/src/utils.cc b/src/utils.cc
index e2231c2..6b93da8 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -25,10 +25,17 @@
#include "UniquePtr.h"
#include "base/unix_file/fd_file.h"
-#include "class_loader.h"
-#include "object.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/class.h"
+#include "mirror/class_loader.h"
+#include "mirror/field.h"
+#include "mirror/field-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
+#include "mirror/string.h"
#include "object_utils.h"
#include "os.h"
+#include "utf.h"
#if !defined(HAVE_POSIX_CLOCKS)
#include <sys/time.h>
@@ -220,14 +227,14 @@
}
}
-std::string PrettyDescriptor(const String* java_descriptor) {
+std::string PrettyDescriptor(const mirror::String* java_descriptor) {
if (java_descriptor == NULL) {
return "null";
}
return PrettyDescriptor(java_descriptor->ToModifiedUtf8());
}
-std::string PrettyDescriptor(const Class* klass) {
+std::string PrettyDescriptor(const mirror::Class* klass) {
if (klass == NULL) {
return "null";
}
@@ -288,7 +295,7 @@
return PrettyDescriptor(descriptor_string);
}
-std::string PrettyField(const Field* f, bool with_type) {
+std::string PrettyField(const mirror::Field* f, bool with_type) {
if (f == NULL) {
return "null";
}
@@ -357,7 +364,7 @@
return PrettyDescriptor(return_type);
}
-std::string PrettyMethod(const AbstractMethod* m, bool with_signature) {
+std::string PrettyMethod(const mirror::AbstractMethod* m, bool with_signature) {
if (m == NULL) {
return "null";
}
@@ -390,7 +397,7 @@
return result;
}
-std::string PrettyTypeOf(const Object* obj) {
+std::string PrettyTypeOf(const mirror::Object* obj) {
if (obj == NULL) {
return "null";
}
@@ -406,7 +413,7 @@
return result;
}
-std::string PrettyClass(const Class* c) {
+std::string PrettyClass(const mirror::Class* c) {
if (c == NULL) {
return "null";
}
@@ -417,7 +424,7 @@
return result;
}
-std::string PrettyClassAndClassLoader(const Class* c) {
+std::string PrettyClassAndClassLoader(const mirror::Class* c) {
if (c == NULL) {
return "null";
}
@@ -613,7 +620,7 @@
return descriptor;
}
-std::string JniShortName(const AbstractMethod* m) {
+std::string JniShortName(const mirror::AbstractMethod* m) {
MethodHelper mh(m);
std::string class_name(mh.GetDeclaringClassDescriptor());
// Remove the leading 'L' and trailing ';'...
@@ -632,7 +639,7 @@
return short_name;
}
-std::string JniLongName(const AbstractMethod* m) {
+std::string JniLongName(const mirror::AbstractMethod* m) {
std::string long_name;
long_name += JniShortName(m);
long_name += "__";
diff --git a/src/utils.h b/src/utils.h
index 640743c..f3c9b7a 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -30,12 +30,15 @@
namespace art {
-class Class;
class DexFile;
+
+namespace mirror {
+class Class;
class Field;
class AbstractMethod;
class Object;
class String;
+} // namespace mirror
enum TimeUnit {
kTimeUnitNanosecond,
@@ -172,21 +175,21 @@
// Returns a human-readable equivalent of 'descriptor'. So "I" would be "int",
// "[[I" would be "int[][]", "[Ljava/lang/String;" would be
// "java.lang.String[]", and so forth.
-std::string PrettyDescriptor(const String* descriptor);
+std::string PrettyDescriptor(const mirror::String* descriptor);
std::string PrettyDescriptor(const std::string& descriptor);
std::string PrettyDescriptor(Primitive::Type type);
-std::string PrettyDescriptor(const Class* klass)
+std::string PrettyDescriptor(const mirror::Class* klass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Returns a human-readable signature for 'f'. Something like "a.b.C.f" or
// "int a.b.C.f" (depending on the value of 'with_type').
-std::string PrettyField(const Field* f, bool with_type = true)
+std::string PrettyField(const mirror::Field* f, bool with_type = true)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
std::string PrettyField(uint32_t field_idx, const DexFile& dex_file, bool with_type = true);
// Returns a human-readable signature for 'm'. Something like "a.b.C.m" or
// "a.b.C.m(II)V" (depending on the value of 'with_signature').
-std::string PrettyMethod(const AbstractMethod* m, bool with_signature = true)
+std::string PrettyMethod(const mirror::AbstractMethod* m, bool with_signature = true)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
std::string PrettyMethod(uint32_t method_idx, const DexFile& dex_file, bool with_signature = true);
@@ -194,7 +197,7 @@
// So given an instance of java.lang.String, the output would
// be "java.lang.String". Given an array of int, the output would be "int[]".
// Given String.class, the output would be "java.lang.Class<java.lang.String>".
-std::string PrettyTypeOf(const Object* obj)
+std::string PrettyTypeOf(const mirror::Object* obj)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Returns a human-readable form of the type at an index in the specified dex file.
@@ -203,11 +206,11 @@
// Returns a human-readable form of the name of the given class.
// Given String.class, the output would be "java.lang.Class<java.lang.String>".
-std::string PrettyClass(const Class* c)
+std::string PrettyClass(const mirror::Class* c)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Returns a human-readable form of the name of the given class with its class loader.
-std::string PrettyClassAndClassLoader(const Class* c)
+std::string PrettyClassAndClassLoader(const mirror::Class* c)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Returns a human-readable size string such as "1MB".
@@ -250,10 +253,10 @@
bool IsValidMemberName(const char* s);
// Returns the JNI native function name for the non-overloaded method 'm'.
-std::string JniShortName(const AbstractMethod* m)
+std::string JniShortName(const mirror::AbstractMethod* m)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Returns the JNI native function name for the overloaded method 'm'.
-std::string JniLongName(const AbstractMethod* m)
+std::string JniLongName(const mirror::AbstractMethod* m)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
bool ReadFileToString(const std::string& file_name, std::string* result);
diff --git a/src/utils_test.cc b/src/utils_test.cc
index f1983be..0966e71 100644
--- a/src/utils_test.cc
+++ b/src/utils_test.cc
@@ -14,8 +14,12 @@
* limitations under the License.
*/
-#include "object.h"
#include "common_test.h"
+#include "mirror/array.h"
+#include "mirror/array-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
+#include "mirror/string.h"
#include "scoped_thread_state_change.h"
#include "sirt_ref.h"
#include "utils.h"
@@ -89,15 +93,15 @@
ScopedObjectAccess soa(Thread::Current());
EXPECT_EQ("null", PrettyTypeOf(NULL));
- SirtRef<String> s(soa.Self(), String::AllocFromModifiedUtf8(soa.Self(), ""));
+ SirtRef<mirror::String> s(soa.Self(), mirror::String::AllocFromModifiedUtf8(soa.Self(), ""));
EXPECT_EQ("java.lang.String", PrettyTypeOf(s.get()));
- SirtRef<ShortArray> a(soa.Self(), ShortArray::Alloc(soa.Self(), 2));
+ SirtRef<mirror::ShortArray> a(soa.Self(), mirror::ShortArray::Alloc(soa.Self(), 2));
EXPECT_EQ("short[]", PrettyTypeOf(a.get()));
- Class* c = class_linker_->FindSystemClass("[Ljava/lang/String;");
+ mirror::Class* c = class_linker_->FindSystemClass("[Ljava/lang/String;");
ASSERT_TRUE(c != NULL);
- Object* o = ObjectArray<String>::Alloc(soa.Self(), c, 0);
+ mirror::Object* o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0);
EXPECT_EQ("java.lang.String[]", PrettyTypeOf(o));
EXPECT_EQ("java.lang.Class<java.lang.String[]>", PrettyTypeOf(o->GetClass()));
}
@@ -105,18 +109,18 @@
TEST_F(UtilsTest, PrettyClass) {
ScopedObjectAccess soa(Thread::Current());
EXPECT_EQ("null", PrettyClass(NULL));
- Class* c = class_linker_->FindSystemClass("[Ljava/lang/String;");
+ mirror::Class* c = class_linker_->FindSystemClass("[Ljava/lang/String;");
ASSERT_TRUE(c != NULL);
- Object* o = ObjectArray<String>::Alloc(soa.Self(), c, 0);
+ mirror::Object* o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0);
EXPECT_EQ("java.lang.Class<java.lang.String[]>", PrettyClass(o->GetClass()));
}
TEST_F(UtilsTest, PrettyClassAndClassLoader) {
ScopedObjectAccess soa(Thread::Current());
EXPECT_EQ("null", PrettyClassAndClassLoader(NULL));
- Class* c = class_linker_->FindSystemClass("[Ljava/lang/String;");
+ mirror::Class* c = class_linker_->FindSystemClass("[Ljava/lang/String;");
ASSERT_TRUE(c != NULL);
- Object* o = ObjectArray<String>::Alloc(soa.Self(), c, 0);
+ mirror::Object* o = mirror::ObjectArray<mirror::String>::Alloc(soa.Self(), c, 0);
EXPECT_EQ("java.lang.Class<java.lang.String[],null>", PrettyClassAndClassLoader(o->GetClass()));
}
@@ -124,9 +128,9 @@
ScopedObjectAccess soa(Thread::Current());
EXPECT_EQ("null", PrettyField(NULL));
- Class* java_lang_String = class_linker_->FindSystemClass("Ljava/lang/String;");
+ mirror::Class* java_lang_String = class_linker_->FindSystemClass("Ljava/lang/String;");
- Field* f;
+ mirror::Field* f;
f = java_lang_String->FindDeclaredInstanceField("count", "I");
EXPECT_EQ("int java.lang.String.count", PrettyField(f));
EXPECT_EQ("java.lang.String.count", PrettyField(f, false));
@@ -193,9 +197,9 @@
TEST_F(UtilsTest, JniShortName_JniLongName) {
ScopedObjectAccess soa(Thread::Current());
- Class* c = class_linker_->FindSystemClass("Ljava/lang/String;");
+ mirror::Class* c = class_linker_->FindSystemClass("Ljava/lang/String;");
ASSERT_TRUE(c != NULL);
- AbstractMethod* m;
+ mirror::AbstractMethod* m;
m = c->FindVirtualMethod("charAt", "(I)C");
ASSERT_TRUE(m != NULL);
diff --git a/src/verifier/method_verifier.cc b/src/verifier/method_verifier.cc
index 7afa6d4..bcac374 100644
--- a/src/verifier/method_verifier.cc
+++ b/src/verifier/method_verifier.cc
@@ -22,13 +22,20 @@
#include "base/stringpiece.h"
#include "class_linker.h"
#include "compiler.h"
-#include "dex_cache.h"
#include "dex_file.h"
#include "dex_instruction.h"
#include "dex_instruction_visitor.h"
+#include "gc/card_table-inl.h"
#include "indenter.h"
#include "intern_table.h"
#include "leb128.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/class.h"
+#include "mirror/class-inl.h"
+#include "mirror/dex_cache.h"
+#include "mirror/field-inl.h"
+#include "mirror/object-inl.h"
+#include "mirror/object_array-inl.h"
#include "object_utils.h"
#include "runtime.h"
#include "verifier/dex_gc_map.h"
@@ -167,11 +174,12 @@
}
}
-MethodVerifier::FailureKind MethodVerifier::VerifyClass(const Class* klass, std::string& error) {
+MethodVerifier::FailureKind MethodVerifier::VerifyClass(const mirror::Class* klass,
+ std::string& error) {
if (klass->IsVerified()) {
return kNoFailure;
}
- Class* super = klass->GetSuperClass();
+ mirror::Class* super = klass->GetSuperClass();
if (super == NULL && StringPiece(ClassHelper(klass).GetDescriptor()) != "Ljava/lang/Object;") {
error = "Verifier rejected class ";
error += PrettyDescriptor(klass);
@@ -199,7 +207,10 @@
}
MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
- DexCache* dex_cache, ClassLoader* class_loader, uint32_t class_def_idx, std::string& error) {
+ mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader,
+ uint32_t class_def_idx,
+ std::string& error) {
const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_idx);
const byte* class_data = dex_file->GetClassData(class_def);
if (class_data == NULL) {
@@ -224,7 +235,8 @@
}
previous_direct_method_idx = method_idx;
InvokeType type = it.GetMethodInvokeType(class_def);
- AbstractMethod* method = linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type);
+ mirror::AbstractMethod* method =
+ linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type);
if (method == NULL) {
DCHECK(Thread::Current()->IsExceptionPending());
// We couldn't resolve the method, but continue regardless.
@@ -258,7 +270,8 @@
}
previous_virtual_method_idx = method_idx;
InvokeType type = it.GetMethodInvokeType(class_def);
- AbstractMethod* method = linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type);
+ mirror::AbstractMethod* method =
+ linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NULL, type);
if (method == NULL) {
DCHECK(Thread::Current()->IsExceptionPending());
// We couldn't resolve the method, but continue regardless.
@@ -288,9 +301,14 @@
}
}
-MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx, const DexFile* dex_file,
- DexCache* dex_cache, ClassLoader* class_loader, uint32_t class_def_idx,
- const DexFile::CodeItem* code_item, AbstractMethod* method, uint32_t method_access_flags) {
+MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx,
+ const DexFile* dex_file,
+ mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader,
+ uint32_t class_def_idx,
+ const DexFile::CodeItem* code_item,
+ mirror::AbstractMethod* method,
+ uint32_t method_access_flags) {
MethodVerifier::FailureKind result = kNoFailure;
uint64_t start_ns = NanoTime();
@@ -326,9 +344,10 @@
}
void MethodVerifier::VerifyMethodAndDump(std::ostream& os, uint32_t dex_method_idx,
- const DexFile* dex_file, DexCache* dex_cache,
- ClassLoader* class_loader, uint32_t class_def_idx,
- const DexFile::CodeItem* code_item, AbstractMethod* method,
+ const DexFile* dex_file, mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ const DexFile::CodeItem* code_item,
+ mirror::AbstractMethod* method,
uint32_t method_access_flags) {
MethodVerifier verifier(dex_file, dex_cache, class_loader, class_def_idx, code_item,
dex_method_idx, method, method_access_flags, true);
@@ -339,11 +358,12 @@
}
std::vector<int32_t> MethodVerifier::DescribeVRegs(uint32_t dex_method_idx,
- const DexFile* dex_file, DexCache* dex_cache,
- ClassLoader* class_loader,
+ const DexFile* dex_file,
+ mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader,
uint32_t class_def_idx,
const DexFile::CodeItem* code_item,
- AbstractMethod* method,
+ mirror::AbstractMethod* method,
uint32_t method_access_flags, uint32_t dex_pc) {
MethodVerifier verifier(dex_file, dex_cache, class_loader, class_def_idx, code_item,
dex_method_idx, method, method_access_flags, true);
@@ -351,9 +371,11 @@
return verifier.DescribeVRegs(dex_pc);
}
-MethodVerifier::MethodVerifier(const DexFile* dex_file, DexCache* dex_cache,
- ClassLoader* class_loader, uint32_t class_def_idx, const DexFile::CodeItem* code_item,
- uint32_t dex_method_idx, AbstractMethod* method, uint32_t method_access_flags,
+MethodVerifier::MethodVerifier(const DexFile* dex_file, mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ const DexFile::CodeItem* code_item,
+ uint32_t dex_method_idx, mirror::AbstractMethod* method,
+ uint32_t method_access_flags,
bool can_load_classes)
: reg_types_(can_load_classes),
work_insn_idx_(-1),
@@ -374,7 +396,7 @@
can_load_classes_(can_load_classes) {
}
-void MethodVerifier::FindLocksAtDexPc(AbstractMethod* m, uint32_t dex_pc,
+void MethodVerifier::FindLocksAtDexPc(mirror::AbstractMethod* m, uint32_t dex_pc,
std::vector<uint32_t>& monitor_enter_dex_pcs) {
MethodHelper mh(m);
MethodVerifier verifier(&mh.GetDexFile(), mh.GetDexCache(), mh.GetClassLoader(),
@@ -569,8 +591,9 @@
// Ensure exception types are resolved so that they don't need resolution to be delivered,
// unresolved exception types will be ignored by exception delivery
if (iterator.GetHandlerTypeIndex() != DexFile::kDexNoIndex16) {
- Class* exception_type = linker->ResolveType(*dex_file_, iterator.GetHandlerTypeIndex(),
- dex_cache_, class_loader_);
+ mirror::Class* exception_type = linker->ResolveType(*dex_file_,
+ iterator.GetHandlerTypeIndex(),
+ dex_cache_, class_loader_);
if (exception_type == NULL) {
DCHECK(Thread::Current()->IsExceptionPending());
Thread::Current()->ClearException();
@@ -1960,7 +1983,8 @@
dec_insn.opcode == Instruction::INVOKE_SUPER_RANGE);
bool is_super = (dec_insn.opcode == Instruction::INVOKE_SUPER ||
dec_insn.opcode == Instruction::INVOKE_SUPER_RANGE);
- AbstractMethod* called_method = VerifyInvocationArgs(dec_insn, METHOD_VIRTUAL, is_range, is_super);
+ mirror::AbstractMethod* called_method = VerifyInvocationArgs(dec_insn, METHOD_VIRTUAL,
+ is_range, is_super);
const char* descriptor;
if (called_method == NULL) {
uint32_t method_idx = dec_insn.vB;
@@ -1982,7 +2006,8 @@
case Instruction::INVOKE_DIRECT:
case Instruction::INVOKE_DIRECT_RANGE: {
bool is_range = (dec_insn.opcode == Instruction::INVOKE_DIRECT_RANGE);
- AbstractMethod* called_method = VerifyInvocationArgs(dec_insn, METHOD_DIRECT, is_range, false);
+ mirror::AbstractMethod* called_method = VerifyInvocationArgs(dec_insn, METHOD_DIRECT,
+ is_range, false);
const char* return_type_descriptor;
bool is_constructor;
if (called_method == NULL) {
@@ -2048,7 +2073,7 @@
case Instruction::INVOKE_STATIC:
case Instruction::INVOKE_STATIC_RANGE: {
bool is_range = (dec_insn.opcode == Instruction::INVOKE_STATIC_RANGE);
- AbstractMethod* called_method = VerifyInvocationArgs(dec_insn, METHOD_STATIC, is_range, false);
+ mirror::AbstractMethod* called_method = VerifyInvocationArgs(dec_insn, METHOD_STATIC, is_range, false);
const char* descriptor;
if (called_method == NULL) {
uint32_t method_idx = dec_insn.vB;
@@ -2070,9 +2095,9 @@
case Instruction::INVOKE_INTERFACE:
case Instruction::INVOKE_INTERFACE_RANGE: {
bool is_range = (dec_insn.opcode == Instruction::INVOKE_INTERFACE_RANGE);
- AbstractMethod* abs_method = VerifyInvocationArgs(dec_insn, METHOD_INTERFACE, is_range, false);
+ mirror::AbstractMethod* abs_method = VerifyInvocationArgs(dec_insn, METHOD_INTERFACE, is_range, false);
if (abs_method != NULL) {
- Class* called_interface = abs_method->GetDeclaringClass();
+ mirror::Class* called_interface = abs_method->GetDeclaringClass();
if (!called_interface->IsInterface() && !called_interface->IsObjectClass()) {
Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected interface class in invoke-interface '"
<< PrettyMethod(abs_method) << "'";
@@ -2558,7 +2583,7 @@
const RegType& MethodVerifier::ResolveClassAndCheckAccess(uint32_t class_idx) {
const char* descriptor = dex_file_->StringByTypeIdx(class_idx);
const RegType& referrer = GetDeclaringClass();
- Class* klass = dex_cache_->GetResolvedType(class_idx);
+ mirror::Class* klass = dex_cache_->GetResolvedType(class_idx);
const RegType& result =
klass != NULL ? reg_types_.FromClass(klass, klass->IsFinal())
: reg_types_.FromDescriptor(class_loader_, descriptor, false);
@@ -2621,7 +2646,8 @@
return *common_super;
}
-AbstractMethod* MethodVerifier::ResolveMethodAndCheckAccess(uint32_t dex_method_idx, MethodType method_type) {
+mirror::AbstractMethod* MethodVerifier::ResolveMethodAndCheckAccess(uint32_t dex_method_idx,
+ MethodType method_type) {
const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx);
const RegType& klass_type = ResolveClassAndCheckAccess(method_id.class_idx_);
if (klass_type.IsConflict()) {
@@ -2633,9 +2659,9 @@
if (klass_type.IsUnresolvedTypes()) {
return NULL; // Can't resolve Class so no more to do here
}
- Class* klass = klass_type.GetClass();
+ mirror::Class* klass = klass_type.GetClass();
const RegType& referrer = GetDeclaringClass();
- AbstractMethod* res_method = dex_cache_->GetResolvedMethod(dex_method_idx);
+ mirror::AbstractMethod* res_method = dex_cache_->GetResolvedMethod(dex_method_idx);
if (res_method == NULL) {
const char* name = dex_file_->GetMethodName(method_id);
std::string signature(dex_file_->CreateMethodSignature(method_id.proto_idx_, NULL));
@@ -2712,11 +2738,12 @@
return res_method;
}
-AbstractMethod* MethodVerifier::VerifyInvocationArgs(const DecodedInstruction& dec_insn,
- MethodType method_type, bool is_range, bool is_super) {
+mirror::AbstractMethod* MethodVerifier::VerifyInvocationArgs(const DecodedInstruction& dec_insn,
+ MethodType method_type, bool is_range,
+ bool is_super) {
// Resolve the method. This could be an abstract or concrete method depending on what sort of call
// we're making.
- AbstractMethod* res_method = ResolveMethodAndCheckAccess(dec_insn.vB, method_type);
+ mirror::AbstractMethod* res_method = ResolveMethodAndCheckAccess(dec_insn.vB, method_type);
if (res_method == NULL) { // error or class is unresolved
return NULL;
}
@@ -2732,7 +2759,7 @@
<< " to super " << PrettyMethod(res_method);
return NULL;
}
- Class* super_klass = super.GetClass();
+ mirror::Class* super_klass = super.GetClass();
if (res_method->GetMethodIndex() >= super_klass->GetVTable()->GetLength()) {
MethodHelper mh(res_method);
Fail(VERIFY_ERROR_NO_METHOD) << "invalid invoke-super from "
@@ -2771,7 +2798,7 @@
return NULL;
}
if (method_type != METHOD_INTERFACE && !actual_arg_type.IsZero()) {
- Class* klass = res_method->GetDeclaringClass();
+ mirror::Class* klass = res_method->GetDeclaringClass();
const RegType& res_method_class = reg_types_.FromClass(klass, klass->IsFinal());
if (!res_method_class.IsAssignableFrom(actual_arg_type)) {
Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "'this' argument '" << actual_arg_type
@@ -2935,7 +2962,7 @@
}
}
-Field* MethodVerifier::GetStaticField(int field_idx) {
+mirror::Field* MethodVerifier::GetStaticField(int field_idx) {
const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
// Check access to class
const RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_);
@@ -2948,7 +2975,7 @@
if (klass_type.IsUnresolvedTypes()) {
return NULL; // Can't resolve Class so no more to do here, will do checking at runtime.
}
- Field* field = Runtime::Current()->GetClassLinker()->ResolveFieldJLS(*dex_file_, field_idx,
+ mirror::Field* field = Runtime::Current()->GetClassLinker()->ResolveFieldJLS(*dex_file_, field_idx,
dex_cache_, class_loader_);
if (field == NULL) {
LOG(INFO) << "unable to resolve static field " << field_idx << " ("
@@ -2970,7 +2997,7 @@
}
}
-Field* MethodVerifier::GetInstanceField(const RegType& obj_type, int field_idx) {
+mirror::Field* MethodVerifier::GetInstanceField(const RegType& obj_type, int field_idx) {
const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
// Check access to class
const RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_);
@@ -2983,7 +3010,7 @@
if (klass_type.IsUnresolvedTypes()) {
return NULL; // Can't resolve Class so no more to do here
}
- Field* field = Runtime::Current()->GetClassLinker()->ResolveFieldJLS(*dex_file_, field_idx,
+ mirror::Field* field = Runtime::Current()->GetClassLinker()->ResolveFieldJLS(*dex_file_, field_idx,
dex_cache_, class_loader_);
if (field == NULL) {
LOG(INFO) << "unable to resolve instance field " << field_idx << " ("
@@ -3005,7 +3032,7 @@
// Cannot infer and check type, however, access will cause null pointer exception
return field;
} else {
- Class* klass = field->GetDeclaringClass();
+ mirror::Class* klass = field->GetDeclaringClass();
const RegType& field_klass = reg_types_.FromClass(klass, klass->IsFinal());
if (obj_type.IsUninitializedTypes() &&
(!IsConstructor() || GetDeclaringClass().Equals(obj_type) ||
@@ -3032,7 +3059,7 @@
void MethodVerifier::VerifyISGet(const DecodedInstruction& dec_insn,
const RegType& insn_type, bool is_primitive, bool is_static) {
uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC;
- Field* field;
+ mirror::Field* field;
if (is_static) {
field = GetStaticField(field_idx);
} else {
@@ -3040,7 +3067,7 @@
field = GetInstanceField(object_type, field_idx);
}
const char* descriptor;
- ClassLoader* loader;
+ mirror::ClassLoader* loader;
if (field != NULL) {
descriptor = FieldHelper(field).GetTypeDescriptor();
loader = field->GetDeclaringClass()->GetClassLoader();
@@ -3085,7 +3112,7 @@
void MethodVerifier::VerifyISPut(const DecodedInstruction& dec_insn,
const RegType& insn_type, bool is_primitive, bool is_static) {
uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC;
- Field* field;
+ mirror::Field* field;
if (is_static) {
field = GetStaticField(field_idx);
} else {
@@ -3093,7 +3120,7 @@
field = GetInstanceField(object_type, field_idx);
}
const char* descriptor;
- ClassLoader* loader;
+ mirror::ClassLoader* loader;
if (field != NULL) {
descriptor = FieldHelper(field).GetTypeDescriptor();
loader = field->GetDeclaringClass()->GetClassLoader();
@@ -3215,7 +3242,7 @@
const RegType& MethodVerifier::GetDeclaringClass() {
if (foo_method_ != NULL) {
- Class* klass = foo_method_->GetDeclaringClass();
+ mirror::Class* klass = foo_method_->GetDeclaringClass();
return reg_types_.FromClass(klass, klass->IsFinal());
} else {
const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
diff --git a/src/verifier/method_verifier.h b/src/verifier/method_verifier.h
index 7779efe..a36a1f9 100644
--- a/src/verifier/method_verifier.h
+++ b/src/verifier/method_verifier.h
@@ -28,7 +28,7 @@
#include "compiler.h"
#include "dex_file.h"
#include "dex_instruction.h"
-#include "object.h"
+#include "mirror/object.h"
#include "reg_type.h"
#include "reg_type_cache.h"
#include "register_line.h"
@@ -156,25 +156,25 @@
};
/* Verify a class. Returns "kNoFailure" on success. */
- static FailureKind VerifyClass(const Class* klass, std::string& error)
+ static FailureKind VerifyClass(const mirror::Class* klass, std::string& error)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- static FailureKind VerifyClass(const DexFile* dex_file, DexCache* dex_cache,
- ClassLoader* class_loader, uint32_t class_def_idx,
+ static FailureKind VerifyClass(const DexFile* dex_file, mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader, uint32_t class_def_idx,
std::string& error)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static void VerifyMethodAndDump(std::ostream& os, uint32_t method_idx, const DexFile* dex_file,
- DexCache* dex_cache, ClassLoader* class_loader,
+ mirror::DexCache* dex_cache, mirror::ClassLoader* class_loader,
uint32_t class_def_idx, const DexFile::CodeItem* code_item,
- AbstractMethod* method, uint32_t method_access_flags)
+ mirror::AbstractMethod* method, uint32_t method_access_flags)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static std::vector<int32_t> DescribeVRegs(uint32_t dex_method_idx,
- const DexFile* dex_file, DexCache* dex_cache,
- ClassLoader* class_loader,
+ const DexFile* dex_file, mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader,
uint32_t class_def_idx,
const DexFile::CodeItem* code_item,
- AbstractMethod* method,
+ mirror::AbstractMethod* method,
uint32_t method_access_flags, uint32_t dex_pc)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -209,7 +209,7 @@
// Fills 'monitor_enter_dex_pcs' with the dex pcs of the monitor-enter instructions corresponding
// to the locks held at 'dex_pc' in 'm'.
- static void FindLocksAtDexPc(AbstractMethod* m, uint32_t dex_pc,
+ static void FindLocksAtDexPc(mirror::AbstractMethod* m, uint32_t dex_pc,
std::vector<uint32_t>& monitor_enter_dex_pcs)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -229,9 +229,11 @@
}
private:
- explicit MethodVerifier(const DexFile* dex_file, DexCache* dex_cache,
- ClassLoader* class_loader, uint32_t class_def_idx, const DexFile::CodeItem* code_item,
- uint32_t method_idx, AbstractMethod* method, uint32_t access_flags, bool can_load_classes)
+ explicit MethodVerifier(const DexFile* dex_file, mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ const DexFile::CodeItem* code_item,
+ uint32_t method_idx, mirror::AbstractMethod* method, uint32_t access_flags,
+ bool can_load_classes)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Adds the given string to the beginning of the last failure message.
@@ -251,9 +253,11 @@
* (3) Iterate through the method, checking type safety and looking
* for code flow problems.
*/
- static FailureKind VerifyMethod(uint32_t method_idx, const DexFile* dex_file, DexCache* dex_cache,
- ClassLoader* class_loader, uint32_t class_def_idx, const DexFile::CodeItem* code_item,
- AbstractMethod* method, uint32_t method_access_flags)
+ static FailureKind VerifyMethod(uint32_t method_idx, const DexFile* dex_file,
+ mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader, uint32_t class_def_idx,
+ const DexFile::CodeItem* code_item,
+ mirror::AbstractMethod* method, uint32_t method_access_flags)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Run verification on the method. Returns true if verification completes and false if the input
@@ -477,11 +481,11 @@
bool is_primitive) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Lookup instance field and fail for resolution violations
- Field* GetInstanceField(const RegType& obj_type, int field_idx)
+ mirror::Field* GetInstanceField(const RegType& obj_type, int field_idx)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Lookup static field and fail for resolution violations
- Field* GetStaticField(int field_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ mirror::Field* GetStaticField(int field_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Perform verification of an iget or sget instruction.
void VerifyISGet(const DecodedInstruction& insn, const RegType& insn_type,
@@ -511,7 +515,7 @@
* the referrer can access the resolved method.
* Does not throw exceptions.
*/
- AbstractMethod* ResolveMethodAndCheckAccess(uint32_t method_idx, MethodType method_type)
+ mirror::AbstractMethod* ResolveMethodAndCheckAccess(uint32_t method_idx, MethodType method_type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
/*
@@ -536,7 +540,7 @@
* Returns the resolved method on success, NULL on failure (with *failure
* set appropriately).
*/
- AbstractMethod* VerifyInvocationArgs(const DecodedInstruction& dec_insn,
+ mirror::AbstractMethod* VerifyInvocationArgs(const DecodedInstruction& dec_insn,
MethodType method_type, bool is_range, bool is_super)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -594,7 +598,7 @@
void ComputeGcMapSizes(size_t* gc_points, size_t* ref_bitmap_bits, size_t* log2_max_gc_pc);
// Describe VRegs at the given dex pc.
- std::vector<int32_t> DescribeVRegs(uint32_t dex_pc);
+ std::vector<int32_t> DescribeVRegs(uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
InsnFlags* CurrentInsnFlags();
@@ -639,13 +643,13 @@
uint32_t dex_method_idx_; // The method we're working on.
// Its object representation if known.
- AbstractMethod* foo_method_ GUARDED_BY(Locks::mutator_lock_);
+ mirror::AbstractMethod* foo_method_ GUARDED_BY(Locks::mutator_lock_);
uint32_t method_access_flags_; // Method's access flags.
const DexFile* dex_file_; // The dex file containing the method.
// The dex_cache for the declaring class of the method.
- DexCache* dex_cache_ GUARDED_BY(Locks::mutator_lock_);
+ mirror::DexCache* dex_cache_ GUARDED_BY(Locks::mutator_lock_);
// The class loader for the declaring class of the method.
- ClassLoader* class_loader_ GUARDED_BY(Locks::mutator_lock_);
+ mirror::ClassLoader* class_loader_ GUARDED_BY(Locks::mutator_lock_);
uint32_t class_def_idx_; // The class def index of the declaring class of the method.
const DexFile::CodeItem* code_item_; // The code item containing the code for the method.
UniquePtr<InsnFlags[]> insn_flags_; // Instruction widths and flags, one entry per code unit.
diff --git a/src/verifier/method_verifier_test.cc b/src/verifier/method_verifier_test.cc
index 8d4c513..5cb3974 100644
--- a/src/verifier/method_verifier_test.cc
+++ b/src/verifier/method_verifier_test.cc
@@ -30,7 +30,7 @@
void VerifyClass(const std::string& descriptor)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
ASSERT_TRUE(descriptor != NULL);
- Class* klass = class_linker_->FindSystemClass(descriptor.c_str());
+ mirror::Class* klass = class_linker_->FindSystemClass(descriptor.c_str());
// Verify the class
std::string error_msg;
diff --git a/src/verifier/reg_type.cc b/src/verifier/reg_type.cc
index ab1da1e..56de179 100644
--- a/src/verifier/reg_type.cc
+++ b/src/verifier/reg_type.cc
@@ -16,9 +16,14 @@
#include "reg_type.h"
+#include "mirror/class.h"
+#include "mirror/class-inl.h"
+#include "mirror/object-inl.h"
#include "object_utils.h"
#include "reg_type_cache.h"
+#include <limits>
+
namespace art {
namespace verifier {
@@ -165,7 +170,7 @@
const RegType& RegType::GetSuperClass(RegTypeCache* cache) const {
if (!IsUnresolvedTypes()) {
- Class* super_klass = GetClass()->GetSuperClass();
+ mirror::Class* super_klass = GetClass()->GetSuperClass();
if (super_klass != NULL) {
return cache->FromClass(super_klass, IsPreciseReference());
} else {
@@ -198,7 +203,7 @@
}
}
-bool RegType::CanAccessMember(Class* klass, uint32_t access_flags) const {
+bool RegType::CanAccessMember(mirror::Class* klass, uint32_t access_flags) const {
if (access_flags & kAccPublic) {
return true;
}
@@ -209,6 +214,62 @@
}
}
+bool RegType::IsObjectArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ if (IsUnresolvedTypes() && !IsUnresolvedMergedReference() && !IsUnresolvedSuperClass()) {
+ // Primitive arrays will always resolve
+ DCHECK(descriptor_[1] == 'L' || descriptor_[1] == '[');
+ return descriptor_[0] == '[';
+ } else if (HasClass()) {
+ mirror::Class* type = GetClass();
+ return type->IsArrayClass() && !type->GetComponentType()->IsPrimitive();
+ } else {
+ return false;
+ }
+}
+
+bool RegType::IsConstantByte() const {
+ return IsConstant() &&
+ ConstantValue() >= std::numeric_limits<jbyte>::min() &&
+ ConstantValue() <= std::numeric_limits<jbyte>::max();
+}
+
+bool RegType::IsConstantShort() const {
+ return IsConstant() &&
+ ConstantValue() >= std::numeric_limits<jshort>::min() &&
+ ConstantValue() <= std::numeric_limits<jshort>::max();
+}
+
+bool RegType::IsConstantChar() const {
+ return IsConstant() && ConstantValue() >= 0 &&
+ ConstantValue() <= std::numeric_limits<jchar>::max();
+}
+
+bool RegType::IsJavaLangObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return IsReference() && GetClass()->IsObjectClass();
+}
+
+bool RegType::IsArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ if (IsUnresolvedTypes() && !IsUnresolvedMergedReference() && !IsUnresolvedSuperClass()) {
+ return descriptor_[0] == '[';
+ } else if (HasClass()) {
+ return GetClass()->IsArrayClass();
+ } else {
+ return false;
+ }
+}
+
+bool RegType::IsJavaLangObjectArray() const {
+ if (HasClass()) {
+ mirror::Class* type = GetClass();
+ return type->IsArrayClass() && type->GetComponentType()->IsObjectClass();
+ }
+ return false;
+}
+
+bool RegType::IsInstantiableTypes() const {
+ return IsUnresolvedTypes() || (IsNonZeroReferenceTypes() && GetClass()->IsInstantiable());
+}
+
bool RegType::IsAssignableFrom(const RegType& src) const {
if (Equals(src)) {
return true;
@@ -363,11 +424,11 @@
// with itself, 0 or Object are handled above.
return reg_types->Conflict();
} else { // Two reference types, compute Join
- Class* c1 = GetClass();
- Class* c2 = incoming_type.GetClass();
+ mirror::Class* c1 = GetClass();
+ mirror::Class* c2 = incoming_type.GetClass();
DCHECK(c1 != NULL && !c1->IsPrimitive());
DCHECK(c2 != NULL && !c2->IsPrimitive());
- Class* join_class = ClassJoin(c1, c2);
+ mirror::Class* join_class = ClassJoin(c1, c2);
if (c1 == join_class && !IsPreciseReference()) {
return *this;
} else if (c2 == join_class && !incoming_type.IsPreciseReference()) {
@@ -382,7 +443,7 @@
}
// See comment in reg_type.h
-Class* RegType::ClassJoin(Class* s, Class* t) {
+mirror::Class* RegType::ClassJoin(mirror::Class* s, mirror::Class* t) {
DCHECK(!s->IsPrimitive()) << PrettyClass(s);
DCHECK(!t->IsPrimitive()) << PrettyClass(t);
if (s == t) {
@@ -392,21 +453,21 @@
} else if (t->IsAssignableFrom(s)) {
return t;
} else if (s->IsArrayClass() && t->IsArrayClass()) {
- Class* s_ct = s->GetComponentType();
- Class* t_ct = t->GetComponentType();
+ mirror::Class* s_ct = s->GetComponentType();
+ mirror::Class* t_ct = t->GetComponentType();
if (s_ct->IsPrimitive() || t_ct->IsPrimitive()) {
// Given the types aren't the same, if either array is of primitive types then the only
// common parent is java.lang.Object
- Class* result = s->GetSuperClass(); // short-cut to java.lang.Object
+ mirror::Class* result = s->GetSuperClass(); // short-cut to java.lang.Object
DCHECK(result->IsObjectClass());
return result;
}
- Class* common_elem = ClassJoin(s_ct, t_ct);
+ mirror::Class* common_elem = ClassJoin(s_ct, t_ct);
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- ClassLoader* class_loader = s->GetClassLoader();
+ mirror::ClassLoader* class_loader = s->GetClassLoader();
std::string descriptor("[");
descriptor += ClassHelper(common_elem).GetDescriptor();
- Class* array_class = class_linker->FindClass(descriptor.c_str(), class_loader);
+ mirror::Class* array_class = class_linker->FindClass(descriptor.c_str(), class_loader);
DCHECK(array_class != NULL);
return array_class;
} else {
@@ -433,8 +494,44 @@
}
}
-std::ostream& operator<<(std::ostream& os, const RegType& rhs)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+void RegType::CheckInvariants() const {
+ bool checked = false;
+ if (IsConstant() || IsConstantLo() || IsConstantHi()) {
+ // Constants: allocation_pc_or_constant_or_merged_types_ will hold the constant value, nothing
+ // else should be defined.
+ CHECK(descriptor_.empty()) << *this;
+ CHECK(klass_ == NULL) << *this;
+ checked = true;
+ }
+ if (IsUnresolvedTypes()) {
+ if (IsUnresolvedMergedReference()) {
+ // Unresolved merged types: allocation pc/merged types should be defined.
+ CHECK(descriptor_.empty()) << *this;
+ CHECK(klass_ == NULL) << *this;
+ CHECK_NE(allocation_pc_or_constant_or_merged_types_, 0U) << *this;
+ } else {
+ // Unresolved types: have a descriptor and no allocation pc/merged types.
+ CHECK(!descriptor_.empty()) << *this;
+ CHECK(klass_ == NULL) << *this;
+ if (!IsUnresolvedAndUninitializedReference()) {
+ CHECK_EQ(allocation_pc_or_constant_or_merged_types_, 0U) << *this;
+ }
+ }
+ checked = true;
+ }
+ if (IsReferenceTypes() && !checked) {
+ // A resolved reference type.
+ CHECK(descriptor_.empty()) << *this;
+ CHECK(klass_ != NULL) << *this;
+ CHECK(klass_->IsClass()) << *this;
+ if (!IsUninitializedReference()) {
+ CHECK_EQ(allocation_pc_or_constant_or_merged_types_, 0U) << *this;
+ }
+ }
+ CHECK(checked = true);
+}
+
+std::ostream& operator<<(std::ostream& os, const RegType& rhs) {
os << rhs.Dump();
return os;
}
diff --git a/src/verifier/reg_type.h b/src/verifier/reg_type.h
index 65ee88a..dc9a33a 100644
--- a/src/verifier/reg_type.h
+++ b/src/verifier/reg_type.h
@@ -18,11 +18,18 @@
#define ART_SRC_VERIFIER_REG_TYPE_H_
#include "base/macros.h"
-#include "object.h"
+#include "primitive.h"
+
+#include "jni.h"
#include <stdint.h>
+#include <set>
+#include <string>
namespace art {
+namespace mirror {
+class Class;
+} // namespace mirror
namespace verifier {
class RegTypeCache;
@@ -189,20 +196,9 @@
bool IsConstantBoolean() const {
return IsConstant() && ConstantValue() >= 0 && ConstantValue() <= 1;
}
- bool IsConstantByte() const {
- return IsConstant() &&
- ConstantValue() >= std::numeric_limits<jbyte>::min() &&
- ConstantValue() <= std::numeric_limits<jbyte>::max();
- }
- bool IsConstantShort() const {
- return IsConstant() &&
- ConstantValue() >= std::numeric_limits<jshort>::min() &&
- ConstantValue() <= std::numeric_limits<jshort>::max();
- }
- bool IsConstantChar() const {
- return IsConstant() && ConstantValue() >= 0 &&
- ConstantValue() <= std::numeric_limits<jchar>::max();
- }
+ bool IsConstantByte() const;
+ bool IsConstantShort() const;
+ bool IsConstantChar() const;
bool IsReferenceTypes() const {
return IsNonZeroReferenceTypes() || IsZero();
@@ -261,38 +257,17 @@
return IsReference() || IsPreciseReference();
}
- Class* GetClass() const {
+ mirror::Class* GetClass() const {
DCHECK(!IsUnresolvedReference());
DCHECK(klass_ != NULL);
return klass_;
}
- bool IsJavaLangObject() const {
- return IsReference() && GetClass()->IsObjectClass();
- }
+ bool IsJavaLangObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool IsArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (IsUnresolvedTypes() && !IsUnresolvedMergedReference() && !IsUnresolvedSuperClass()) {
- return descriptor_[0] == '[';
- } else if (HasClass()) {
- return GetClass()->IsArrayClass();
- } else {
- return false;
- }
- }
+ bool IsArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool IsObjectArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (IsUnresolvedTypes() && !IsUnresolvedMergedReference() && !IsUnresolvedSuperClass()) {
- // Primitive arrays will always resolve
- DCHECK(descriptor_[1] == 'L' || descriptor_[1] == '[');
- return descriptor_[0] == '[';
- } else if (HasClass()) {
- Class* type = GetClass();
- return type->IsArrayClass() && !type->GetComponentType()->IsPrimitive();
- } else {
- return false;
- }
- }
+ bool IsObjectArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Primitive::Type GetPrimitiveType() const {
if (IsNonZeroReferenceTypes()) {
@@ -317,17 +292,9 @@
}
}
- bool IsJavaLangObjectArray() const {
- if (HasClass()) {
- Class* type = GetClass();
- return type->IsArrayClass() && type->GetComponentType()->IsObjectClass();
- }
- return false;
- }
+ bool IsJavaLangObjectArray() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- bool IsInstantiableTypes() const {
- return IsUnresolvedTypes() || (IsNonZeroReferenceTypes() && GetClass()->IsInstantiable());
- }
+ bool IsInstantiableTypes() const;
std::string GetDescriptor() const {
DCHECK(IsUnresolvedTypes() && !IsUnresolvedMergedReference() && !IsUnresolvedSuperClass());
@@ -364,7 +331,7 @@
bool CanAccess(const RegType& other) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Can this type access a member with the given properties?
- bool CanAccessMember(Class* klass, uint32_t access_flags) const
+ bool CanAccessMember(mirror::Class* klass, uint32_t access_flags) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Can this type be assigned by src?
@@ -393,47 +360,48 @@
*
* [1] Java bytecode verification: algorithms and formalizations, Xavier Leroy
*/
- static Class* ClassJoin(Class* s, Class* t)
+ static mirror::Class* ClassJoin(mirror::Class* s, mirror::Class* t)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
private:
friend class RegTypeCache;
- RegType(Type type, Class* klass,
+ RegType(Type type, mirror::Class* klass,
uint32_t allocation_pc_or_constant_or_merged_types, uint16_t cache_id)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: type_(type), klass_(klass),
allocation_pc_or_constant_or_merged_types_(allocation_pc_or_constant_or_merged_types),
cache_id_(cache_id) {
- DCHECK(IsConstant() || IsConstantLo() || IsConstantHi() ||
- IsUninitializedTypes() || IsUnresolvedMergedReference() || IsUnresolvedSuperClass() ||
- allocation_pc_or_constant_or_merged_types == 0);
- if (!IsConstant() && !IsLongConstant() && !IsLongConstantHigh() && !IsUndefined() &&
- !IsConflict() && !IsUnresolvedMergedReference() && !IsUnresolvedSuperClass()) {
- DCHECK(klass_ != NULL);
- DCHECK(klass_->IsClass());
- DCHECK(!IsUnresolvedTypes());
- }
+#ifndef NDEBUG
+ CheckInvariants();
+#endif
}
RegType(Type type, const std::string& descriptor, uint32_t allocation_pc, uint16_t cache_id)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
: type_(type),
klass_(NULL),
descriptor_(descriptor),
allocation_pc_or_constant_or_merged_types_(allocation_pc),
cache_id_(cache_id) {
+#ifndef NDEBUG
+ CheckInvariants();
+#endif
}
+ void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
const Type type_; // The current type of the register
- // If known the type of the register...
- Class* klass_;
+ // For reference types, if known the type of the register...
+ mirror::Class* klass_;
// ...else a String for the descriptor.
std::string descriptor_;
// Overloaded field that:
// - if IsConstant() holds a 32bit constant value
- // - is IsReference() holds the allocation_pc or kInitArgAddr for an initialized reference or
- // kUninitThisArgAddr for an uninitialized this ptr
+ // - is IsUninitializedReference()/IsUnresolvedAndUninitializedReference() holds the pc the
+ // instance in the register was being allocated.
const uint32_t allocation_pc_or_constant_or_merged_types_;
// A RegType cache densely encodes types, this is the location in the cache for this type
@@ -441,7 +409,8 @@
DISALLOW_COPY_AND_ASSIGN(RegType);
};
-std::ostream& operator<<(std::ostream& os, const RegType& rhs);
+std::ostream& operator<<(std::ostream& os, const RegType& rhs)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
} // namespace verifier
} // namespace art
diff --git a/src/verifier/reg_type_cache.cc b/src/verifier/reg_type_cache.cc
index 3bf5ad8..6ca54de 100644
--- a/src/verifier/reg_type_cache.cc
+++ b/src/verifier/reg_type_cache.cc
@@ -16,6 +16,8 @@
#include "reg_type_cache.h"
+#include "mirror/class-inl.h"
+#include "mirror/object-inl.h"
#include "object_utils.h"
namespace art {
@@ -57,7 +59,7 @@
}
}
-const RegType& RegTypeCache::FromDescriptor(ClassLoader* loader, const char* descriptor,
+const RegType& RegTypeCache::FromDescriptor(mirror::ClassLoader* loader, const char* descriptor,
bool precise) {
return From(RegTypeFromDescriptor(descriptor), loader, descriptor, precise);
}
@@ -67,14 +69,14 @@
return (entry->IsPreciseReference() == precise) || (entry->GetClass()->IsFinal() && !precise);
}
-const RegType& RegTypeCache::From(RegType::Type type, ClassLoader* loader, const char* descriptor,
- bool precise) {
+const RegType& RegTypeCache::From(RegType::Type type, mirror::ClassLoader* loader,
+ const char* descriptor, bool precise) {
if (type <= RegType::kRegTypeLastFixedLocation) {
// entries should be sized greater than primitive types
DCHECK_GT(entries_.size(), static_cast<size_t>(type));
RegType* entry = entries_[type];
if (entry == NULL) {
- Class* c = NULL;
+ mirror::Class* c = NULL;
if (strlen(descriptor) != 0) {
c = Runtime::Current()->GetClassLinker()->FindSystemClass(descriptor);
}
@@ -100,7 +102,7 @@
}
}
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- Class* c;
+ mirror::Class* c;
if (can_load_classes_) {
c = class_linker->FindClass(descriptor, loader);
} else {
@@ -125,7 +127,8 @@
DCHECK(!Thread::Current()->IsExceptionPending());
}
if (IsValidDescriptor(descriptor)) {
- RegType* entry = new RegType(RegType::kRegTypeUnresolvedReference, descriptor, 0, entries_.size());
+ RegType* entry =
+ new RegType(RegType::kRegTypeUnresolvedReference, descriptor, 0, entries_.size());
entries_.push_back(entry);
return *entry;
} else {
@@ -137,7 +140,7 @@
}
}
-const RegType& RegTypeCache::FromClass(Class* klass, bool precise) {
+const RegType& RegTypeCache::FromClass(mirror::Class* klass, bool precise) {
if (klass->IsPrimitive()) {
RegType::Type type = RegTypeFromPrimitiveType(klass->GetPrimitiveType());
// entries should be sized greater than primitive types
@@ -233,7 +236,7 @@
entry = new RegType(RegType::kRegTypeUnresolvedAndUninitializedReference,
descriptor, allocation_pc, entries_.size());
} else {
- Class* klass = type.GetClass();
+ mirror::Class* klass = type.GetClass();
for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
RegType* cur_entry = entries_[i];
if (cur_entry->IsUninitializedReference() &&
@@ -261,7 +264,7 @@
}
entry = new RegType(RegType::kRegTypeUnresolvedReference, descriptor, 0, entries_.size());
} else {
- Class* klass = uninit_type.GetClass();
+ mirror::Class* klass = uninit_type.GetClass();
for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
RegType* cur_entry = entries_[i];
if (cur_entry->IsPreciseReference() && cur_entry->GetClass() == klass) {
@@ -274,6 +277,18 @@
return *entry;
}
+const RegType& RegTypeCache::ByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return FromCat1Const(std::numeric_limits<jbyte>::min(), false);
+}
+
+const RegType& RegTypeCache::ShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return FromCat1Const(std::numeric_limits<jshort>::min(), false);
+}
+
+const RegType& RegTypeCache::IntConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ return FromCat1Const(std::numeric_limits<jint>::max(), false);
+}
+
const RegType& RegTypeCache::UninitializedThisArgument(const RegType& type) {
// TODO: implement descriptor version.
RegType* entry;
@@ -289,7 +304,7 @@
entry = new RegType(RegType::kRegTypeUnresolvedAndUninitializedThisReference, descriptor, 0,
entries_.size());
} else {
- Class* klass = type.GetClass();
+ mirror::Class* klass = type.GetClass();
for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
RegType* cur_entry = entries_[i];
if (cur_entry->IsUninitializedThisReference() && cur_entry->GetClass() == klass) {
@@ -320,7 +335,8 @@
}
const RegType& RegTypeCache::FromCat1Const(int32_t value, bool precise) {
- RegType::Type wanted_type = precise ? RegType::kRegTypePreciseConst : RegType::kRegTypeImpreciseConst;
+ RegType::Type wanted_type =
+ precise ? RegType::kRegTypePreciseConst : RegType::kRegTypeImpreciseConst;
for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
RegType* cur_entry = entries_[i];
if (cur_entry->GetType() == wanted_type && cur_entry->ConstantValue() == value) {
@@ -333,7 +349,8 @@
}
const RegType& RegTypeCache::FromCat2ConstLo(int32_t value, bool precise) {
- RegType::Type wanted_type = precise ? RegType::kRegTypePreciseConstLo : RegType::kRegTypeImpreciseConstLo;
+ RegType::Type wanted_type =
+ precise ? RegType::kRegTypePreciseConstLo : RegType::kRegTypeImpreciseConstLo;
for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
RegType* cur_entry = entries_[i];
if (cur_entry->GetType() == wanted_type && cur_entry->ConstantValueLo() == value) {
@@ -346,7 +363,8 @@
}
const RegType& RegTypeCache::FromCat2ConstHi(int32_t value, bool precise) {
- RegType::Type wanted_type = precise ? RegType::kRegTypePreciseConstHi : RegType::kRegTypeImpreciseConstHi;
+ RegType::Type wanted_type =
+ precise ? RegType::kRegTypePreciseConstHi : RegType::kRegTypeImpreciseConstHi;
for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
RegType* cur_entry = entries_[i];
if (cur_entry->GetType() == wanted_type && cur_entry->ConstantValueHi() == value) {
@@ -358,14 +376,14 @@
return *entry;
}
-const RegType& RegTypeCache::GetComponentType(const RegType& array, ClassLoader* loader) {
+const RegType& RegTypeCache::GetComponentType(const RegType& array, mirror::ClassLoader* loader) {
CHECK(array.IsArrayTypes());
if (array.IsUnresolvedTypes()) {
std::string descriptor(array.GetDescriptor());
std::string component(descriptor.substr(1, descriptor.size() - 1));
return FromDescriptor(loader, component.c_str(), false);
} else {
- Class* klass = array.GetClass()->GetComponentType();
+ mirror::Class* klass = array.GetClass()->GetComponentType();
return FromClass(klass, klass->IsFinal());
}
}
diff --git a/src/verifier/reg_type_cache.h b/src/verifier/reg_type_cache.h
index 54f42fd..adab18c 100644
--- a/src/verifier/reg_type_cache.h
+++ b/src/verifier/reg_type_cache.h
@@ -21,7 +21,13 @@
#include "base/stl_util.h"
#include "reg_type.h"
+#include <vector>
+
namespace art {
+namespace mirror {
+class Class;
+class ClassLoader;
+} // namespace mirror
namespace verifier {
class RegTypeCache {
@@ -41,20 +47,25 @@
return *result;
}
- const RegType& From(RegType::Type type, ClassLoader* loader, const char* descriptor, bool precise)
+ const RegType& From(RegType::Type type, mirror::ClassLoader* loader, const char* descriptor,
+ bool precise)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- const RegType& FromClass(Class* klass, bool precise)
+ const RegType& FromClass(mirror::Class* klass, bool precise)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
const RegType& FromCat1Const(int32_t value, bool precise)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- const RegType& FromCat2ConstLo(int32_t value, bool precise);
- const RegType& FromCat2ConstHi(int32_t value, bool precise);
- const RegType& FromDescriptor(ClassLoader* loader, const char* descriptor, bool precise)
+ const RegType& FromCat2ConstLo(int32_t value, bool precise)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const RegType& FromCat2ConstHi(int32_t value, bool precise)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const RegType& FromDescriptor(mirror::ClassLoader* loader, const char* descriptor, bool precise)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
const RegType& FromType(RegType::Type)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- const RegType& FromUnresolvedMerge(const RegType& left, const RegType& right);
- const RegType& FromUnresolvedSuperClass(const RegType& child);
+ const RegType& FromUnresolvedMerge(const RegType& left, const RegType& right)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const RegType& FromUnresolvedSuperClass(const RegType& child)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
const RegType& Boolean() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
return FromType(RegType::kRegTypeBoolean);
@@ -117,25 +128,22 @@
return FromCat1Const(0, true);
}
- const RegType& Uninitialized(const RegType& type, uint32_t allocation_pc);
+ const RegType& Uninitialized(const RegType& type, uint32_t allocation_pc)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Create an uninitialized 'this' argument for the given type.
- const RegType& UninitializedThisArgument(const RegType& type);
- const RegType& FromUninitialized(const RegType& uninit_type);
+ const RegType& UninitializedThisArgument(const RegType& type)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const RegType& FromUninitialized(const RegType& uninit_type)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Representatives of various constant types. When merging constants we can't infer a type,
// (an int may later be used as a float) so we select these representative values meaning future
// merges won't know the exact constant value but have some notion of its size.
- const RegType& ByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return FromCat1Const(std::numeric_limits<jbyte>::min(), false);
- }
- const RegType& ShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return FromCat1Const(std::numeric_limits<jshort>::min(), false);
- }
- const RegType& IntConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return FromCat1Const(std::numeric_limits<jint>::max(), false);
- }
+ const RegType& ByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const RegType& ShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ const RegType& IntConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- const RegType& GetComponentType(const RegType& array, ClassLoader* loader)
+ const RegType& GetComponentType(const RegType& array, mirror::ClassLoader* loader)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void Dump(std::ostream& os) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
diff --git a/src/verifier/register_line.h b/src/verifier/register_line.h
index c6c19f8..8253f51 100644
--- a/src/verifier/register_line.h
+++ b/src/verifier/register_line.h
@@ -23,6 +23,7 @@
#include "dex_instruction.h"
#include "reg_type.h"
#include "safe_map.h"
+#include "UniquePtr.h"
namespace art {
namespace verifier {
@@ -135,7 +136,8 @@
* reference type. This is called when an appropriate constructor is invoked -- all copies of
* the reference must be marked as initialized.
*/
- void MarkRefsAsInitialized(const RegType& uninit_type);
+ void MarkRefsAsInitialized(const RegType& uninit_type)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
/*
* Check constraints on constructor return. Specifically, make sure that the "this" argument got
@@ -245,10 +247,10 @@
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Verify/push monitor onto the monitor stack, locking the value in reg_idx at location insn_idx.
- void PushMonitor(uint32_t reg_idx, int32_t insn_idx);
+ void PushMonitor(uint32_t reg_idx, int32_t insn_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Verify/pop monitor from monitor stack ensuring that we believe the monitor is locked
- void PopMonitor(uint32_t reg_idx);
+ void PopMonitor(uint32_t reg_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
// Stack of currently held monitors and where they were locked
size_t MonitorStackDepth() const {
diff --git a/src/well_known_classes.cc b/src/well_known_classes.cc
index 9752c74..5012f1b 100644
--- a/src/well_known_classes.cc
+++ b/src/well_known_classes.cc
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include "base/logging.h"
+#include "mirror/class.h"
#include "ScopedLocalRef.h"
#include "thread.h"
@@ -198,8 +199,8 @@
java_lang_Runtime_nativeLoad = CacheMethod(env, java_lang_Runtime.get(), true, "nativeLoad", "(Ljava/lang/String;Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/String;");
}
-Class* WellKnownClasses::ToClass(jclass global_jclass) {
- return reinterpret_cast<Class*>(Thread::Current()->DecodeJObject(global_jclass));
+mirror::Class* WellKnownClasses::ToClass(jclass global_jclass) {
+ return reinterpret_cast<mirror::Class*>(Thread::Current()->DecodeJObject(global_jclass));
}
} // namespace art
diff --git a/src/well_known_classes.h b/src/well_known_classes.h
index 10afca9..92a207a 100644
--- a/src/well_known_classes.h
+++ b/src/well_known_classes.h
@@ -21,8 +21,9 @@
#include "jni.h"
namespace art {
-
+namespace mirror {
class Class;
+} // namespace mirror
// Various classes used in JNI. We cache them so we don't have to keep looking
// them up. Similar to libcore's JniConstants (except there's no overlap, so
@@ -33,7 +34,7 @@
static void Init(JNIEnv* env); // Run before native methods are registered.
static void LateInit(JNIEnv* env); // Run after native methods are registered.
- static Class* ToClass(jclass global_jclass)
+ static mirror::Class* ToClass(jclass global_jclass)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
static jclass com_android_dex_Dex;
diff --git a/test/ReferenceMap/stack_walk_refmap_jni.cc b/test/ReferenceMap/stack_walk_refmap_jni.cc
index 60182e2..5109b82 100644
--- a/test/ReferenceMap/stack_walk_refmap_jni.cc
+++ b/test/ReferenceMap/stack_walk_refmap_jni.cc
@@ -19,7 +19,9 @@
#include "UniquePtr.h"
#include "class_linker.h"
#include "gc_map.h"
-#include "object.h"
+#include "mirror/abstract_method.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object_array-inl.h"
#include "object_utils.h"
#include "scoped_thread_state_change.h"
#include "thread.h"
@@ -48,7 +50,7 @@
}
bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* m = GetMethod();
+ mirror::AbstractMethod* m = GetMethod();
if (!m || m->IsNative() || m->IsRuntimeMethod() || IsShadowFrame()) {
return true;
}
diff --git a/test/StackWalk/stack_walk_jni.cc b/test/StackWalk/stack_walk_jni.cc
index dccd69f..a16d896 100644
--- a/test/StackWalk/stack_walk_jni.cc
+++ b/test/StackWalk/stack_walk_jni.cc
@@ -19,7 +19,9 @@
#include "UniquePtr.h"
#include "class_linker.h"
#include "gc_map.h"
-#include "object.h"
+#include "mirror/abstract_method.h"
+#include "mirror/abstract_method-inl.h"
+#include "mirror/object_array-inl.h"
#include "object_utils.h"
#include "jni.h"
#include "scoped_thread_state_change.h"
@@ -46,7 +48,7 @@
}
bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- AbstractMethod* m = GetMethod();
+ mirror::AbstractMethod* m = GetMethod();
CHECK(m != NULL);
LOG(INFO) << "At " << PrettyMethod(m, false);