Make class roots an image root
Change-Id: I1f1513bf34caa736c0dd7518a92f493b4573d776
diff --git a/src/class_linker.cc b/src/class_linker.cc
index d3a6ed0..1049107 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -563,15 +563,6 @@
return oat_file;
}
-struct ClassLinker::InitFromImageCallbackState {
- ClassLinker* class_linker;
-
- Class* class_roots[kClassRootsMax];
-
- typedef std::tr1::unordered_map<std::string, ClassRoot> Table;
- Table descriptor_to_class_root;
-};
-
void ClassLinker::InitFromImage() {
const Runtime* runtime = Runtime::Current();
if (runtime->IsVerboseStartup()) {
@@ -614,23 +605,12 @@
HeapBitmap* heap_bitmap = Heap::GetLiveBits();
DCHECK(heap_bitmap != NULL);
- InitFromImageCallbackState state;
- state.class_linker = this;
- for (size_t i = 0; i < kClassRootsMax; i++) {
- ClassRoot class_root = static_cast<ClassRoot>(i);
- state.descriptor_to_class_root[GetClassRootDescriptor(class_root)] = class_root;
- }
-
// reinit clases_ table
- heap_bitmap->Walk(InitFromImageCallback, &state);
+ heap_bitmap->Walk(InitFromImageCallback, this);
// reinit class_roots_
- Class* object_array_class = state.class_roots[kObjectArrayClass];
- class_roots_ = ObjectArray<Class>::Alloc(object_array_class, kClassRootsMax);
- for (size_t i = 0; i < kClassRootsMax; i++) {
- ClassRoot class_root = static_cast<ClassRoot>(i);
- SetClassRoot(class_root, state.class_roots[class_root]);
- }
+ Object* class_roots_object = spaces[0]->GetImageHeader().GetImageRoot(ImageHeader::kClassRoots);
+ class_roots_ = class_roots_object->AsObjectArray<Class>();
// reinit array_interfaces_ from any array class instance, they should all be ==
array_interfaces_ = GetClassRoot(kObjectArrayClass)->GetInterfaces();
@@ -660,10 +640,10 @@
void ClassLinker::InitFromImageCallback(Object* obj, void* arg) {
DCHECK(obj != NULL);
DCHECK(arg != NULL);
- InitFromImageCallbackState* state = reinterpret_cast<InitFromImageCallbackState*>(arg);
+ ClassLinker* class_linker = reinterpret_cast<ClassLinker*>(arg);
if (obj->IsString()) {
- state->class_linker->intern_table_->RegisterStrong(obj->AsString());
+ class_linker->intern_table_->RegisterStrong(obj->AsString());
return;
}
if (!obj->IsClass()) {
@@ -680,15 +660,7 @@
std::string descriptor = klass->GetDescriptor()->ToModifiedUtf8();
// restore class to ClassLinker::classes_ table
- state->class_linker->InsertClass(descriptor, klass);
-
- // check if this is a root, if so, register it
- typedef InitFromImageCallbackState::Table::const_iterator It; // TODO: C++0x auto
- It it = state->descriptor_to_class_root.find(descriptor);
- if (it != state->descriptor_to_class_root.end()) {
- ClassRoot class_root = it->second;
- state->class_roots[class_root] = klass;
- }
+ class_linker->InsertClass(descriptor, klass);
}
// Keep in sync with InitCallback. Anything we visit, we need to
@@ -964,8 +936,7 @@
klass->SetDescriptor(intern_table_->InternStrong(descriptor));
}
uint32_t access_flags = dex_class_def.access_flags_;
- // Make sure there aren't any "bonus" flags set, since we use them for runtime
- // state.
+ // Make sure there aren't any "bonus" flags set, since we use them for runtime state.
CHECK_EQ(access_flags & ~kAccClassFlagsMask, 0U);
klass->SetAccessFlags(access_flags);
klass->SetClassLoader(class_loader);
diff --git a/src/class_linker.h b/src/class_linker.h
index 747a6e4..7f08a9b 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -377,6 +377,11 @@
class_roots_->Set(class_root, klass);
}
+ ObjectArray<Class>* GetClassRoots() {
+ DCHECK(class_roots_ != NULL);
+ return class_roots_;
+ }
+
static const char* class_roots_descriptors_[];
const char* GetClassRootDescriptor(ClassRoot class_root) {
@@ -397,7 +402,7 @@
friend class ObjectTest;
FRIEND_TEST(ObjectTest, AllocObjectArray);
FRIEND_TEST(ExceptionTest, FindExceptionHandler);
- friend class ImageWriter; // for GetDexCaches
+ friend class ImageWriter; // for GetClassRoots
DISALLOW_COPY_AND_ASSIGN(ClassLinker);
};
diff --git a/src/image.h b/src/image.h
index 4a2efc5..a15ead7 100644
--- a/src/image.h
+++ b/src/image.h
@@ -71,6 +71,7 @@
kCalleeSaveMethod,
kOatLocation,
kDexCaches,
+ kClassRoots,
kImageRootsMax,
};
diff --git a/src/image_writer.cc b/src/image_writer.cc
index 2b2ada4..f223136 100644
--- a/src/image_writer.cc
+++ b/src/image_writer.cc
@@ -147,6 +147,8 @@
String::AllocFromModifiedUtf8(oat_file_->GetLocation().c_str()));
image_roots->Set(ImageHeader::kDexCaches,
dex_caches);
+ image_roots->Set(ImageHeader::kClassRoots,
+ class_linker->GetClassRoots());
for (int i = 0; i < ImageHeader::kImageRootsMax; i++) {
CHECK(image_roots->Get(i) != NULL);
}
diff --git a/src/oatdump.cc b/src/oatdump.cc
index e96b25c..3856f34 100644
--- a/src/oatdump.cc
+++ b/src/oatdump.cc
@@ -51,6 +51,7 @@
"kCalleeSaveMethod",
"kOatLocation",
"kDexCaches",
+ "kClassRoots",
};
class OatDump {
@@ -73,8 +74,18 @@
CHECK_EQ(arraysize(image_roots_descriptions_), size_t(ImageHeader::kImageRootsMax));
for (int i = 0; i < ImageHeader::kImageRootsMax; i++) {
ImageHeader::ImageRoot image_root = static_cast<ImageHeader::ImageRoot>(i);
- os << StringPrintf("%s: %p\n",
- image_roots_descriptions_[i], image_header.GetImageRoot(image_root));
+ const char* image_root_description = image_roots_descriptions_[i];
+ Object* image_root_object = image_header.GetImageRoot(image_root);
+ os << StringPrintf("%s: %p\n", image_root_description, image_root_object);
+ if (image_root_object->IsObjectArray()) {
+ // 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);
+ // = image_root_object->AsObjectArray<Object>();
+ for (int i = 0; i < image_root_object_array->GetLength(); i++) {
+ os << StringPrintf("\t%d: %p\n", i, image_root_object_array->Get(i));
+ }
+ }
}
os << "\n";
diff --git a/src/object.h b/src/object.h
index 7634807..42235b8 100644
--- a/src/object.h
+++ b/src/object.h
@@ -248,16 +248,10 @@
bool IsObjectArray() const;
template<class T>
- ObjectArray<T>* AsObjectArray() {
- DCHECK(IsObjectArray());
- return down_cast<ObjectArray<T>*>(this);
- }
+ ObjectArray<T>* AsObjectArray();
template<class T>
- const ObjectArray<T>* AsObjectArray() const {
- DCHECK(IsObjectArray());
- return down_cast<const ObjectArray<T>*>(this);
- }
+ const ObjectArray<T>* AsObjectArray() const;
bool IsArrayInstance() const;
@@ -2106,6 +2100,18 @@
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();
}
diff --git a/src/runtime.h b/src/runtime.h
index bd2c7a2..8252a60 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -191,7 +191,7 @@
// The host prefix is used during cross compilation. It is removed
// from the start of host paths such as:
// $ANDROID_PRODUCT_OUT/system/framework/core.oat
- // to produce target paths such as
+ // to produce target paths such as
// /system/framework/core.oat
// Similarly it is prepended to target paths to arrive back at a
// host past. In both cases this is necessary because image and oat