Simplify command line arguments
Change-Id: I9d6902b0c447fd8fbe5600fd36139791b2ceefb7
diff --git a/Android.mk b/Android.mk
index bd37967..35825e1 100644
--- a/Android.mk
+++ b/Android.mk
@@ -113,7 +113,7 @@
@echo test-art-target-run-test PASSED
.PHONY: test-art-target-run-test-002
-test-art-target-run-test-002:
+test-art-target-run-test-002: test-art-target-sync
art/test/run-test 002
@echo test-art-target-run-test-002 PASSED
@@ -134,7 +134,7 @@
test-art-target-oat-process-am: $(TARGET_OUT_JAVA_LIBRARIES)/am.oat test-art-target-sync
adb remount
adb sync
- adb shell sh -c "export CLASSPATH=/system/framework/am.jar && oat_processd /system/bin/app_process -Xbootimage:/system/framework/boot.art -Ximage:/system/framework/am.oat /system/bin com.android.commands.am.Am start http://android.com && touch /sdcard/test-art-target-process-am"
+ adb shell sh -c "export CLASSPATH=/system/framework/am.jar && oat_processd /system/bin/app_process -Ximage:/system/framework/boot.art -Ximage:/system/framework/am.oat /system/bin com.android.commands.am.Am start http://android.com && touch /sdcard/test-art-target-process-am"
$(hide) (adb pull /sdcard/test-art-target-process-am /tmp/ && echo test-art-target-process-am PASSED) || echo test-art-target-process-am FAILED
$(hide) rm /tmp/test-art-target-process-am
@@ -158,7 +158,7 @@
sleep 30; \
fi
adb shell kill `adb shell ps | fgrep com.android.calculator2 | sed -e 's/[^ ]* *\([0-9]*\).*/\1/'`
- adb shell sh -c "export CLASSPATH=/system/framework/am.jar && oat_processd /system/bin/app_process -Xbootimage:/system/framework/boot.art -Ximage:/system/framework/am.oat /system/bin com.android.commands.am.Am start -a android.intent.action.MAIN -n com.android.calculator2/.Calculator && touch /sdcard/test-art-target-process-Calculator"
+ adb shell sh -c "export CLASSPATH=/system/framework/am.jar && oat_processd /system/bin/app_process -Ximage:/system/framework/boot.art -Ximage:/system/framework/am.oat /system/bin com.android.commands.am.Am start -a android.intent.action.MAIN -n com.android.calculator2/.Calculator && touch /sdcard/test-art-target-process-Calculator"
$(hide) (adb pull /sdcard/test-art-target-process-Calculator /tmp/ && echo test-art-target-process-Calculator PASSED) || echo test-art-target-process-Calculator FAILED
$(hide) rm /tmp/test-art-target-process-Calculator
@@ -170,17 +170,17 @@
.PHONY: dump-oat-core
dump-oat-core: $(TARGET_CORE_OAT) $(OATDUMP)
- $(OATDUMP) $(addprefix --dex-file=,$(TARGET_CORE_DEX)) --oat=$(TARGET_CORE_OAT) --image=$(TARGET_CORE_IMG) --strip-prefix=$(PRODUCT_OUT) --output=/tmp/core.oatdump.txt
+ $(OATDUMP) --image=$(TARGET_CORE_IMG) --host-prefix=$(PRODUCT_OUT) --output=/tmp/core.oatdump.txt
@echo Output in /tmp/core.oatdump.txt
.PHONY: dump-oat-boot
dump-oat-boot: $(TARGET_BOOT_OAT) $(OATDUMP)
- $(OATDUMP) $(addprefix --dex-file=,$(TARGET_BOOT_DEX)) --oat=$(TARGET_BOOT_OAT) --image=$(TARGET_BOOT_IMG) --strip-prefix=$(PRODUCT_OUT) --output=/tmp/boot.oatdump.txt
+ $(OATDUMP) --image=$(TARGET_BOOT_IMG) --host-prefix=$(PRODUCT_OUT) --output=/tmp/boot.oatdump.txt
@echo Output in /tmp/boot.oatdump.txt
.PHONY: dump-oat-Calculator
dump-oat-Calculator: $(TARGET_OUT_APPS)/Calculator.oat $(TARGET_BOOT_OAT) $(OATDUMP)
- $(OATDUMP) --dex-file=$(TARGET_OUT_APPS)/Calculator.apk --oat=$< --image=$(patsubst %.oat,%.art,$<) $(addprefix --boot-dex-file=,$(TARGET_BOOT_DEX)) --boot-oat=$(TARGET_BOOT_OAT) --boot-image=$(TARGET_BOOT_IMG) --strip-prefix=$(PRODUCT_OUT) --output=/tmp/Calculator.oatdump.txt
+ $(OATDUMP) --image=$(patsubst %.oat,%.art,$<) --boot-image=$(TARGET_BOOT_IMG) --host-prefix=$(PRODUCT_OUT) --output=/tmp/Calculator.oatdump.txt
@echo Output in /tmp/Calculator.oatdump.txt
diff --git a/build/Android.oat.mk b/build/Android.oat.mk
index 52d5621..4839667 100644
--- a/build/Android.oat.mk
+++ b/build/Android.oat.mk
@@ -50,7 +50,7 @@
# TODO: change DEX2OATD to order-only prerequisite when output is stable
$(TARGET_CORE_OAT): $(TARGET_CORE_DEX) $(DEX2OAT)
@echo "target dex2oat: $@ ($<)"
- $(hide) $(DEX2OAT) -Xms32m -Xmx32m $(addprefix --dex-file=,$(filter-out $(DEX2OAT),$^)) --oat=$@ --image=$(TARGET_CORE_IMG) --base=$(IMG_TARGET_BASE_ADDRESS) --strip-prefix=$(PRODUCT_OUT)
+ $(hide) $(DEX2OAT) -Xms32m -Xmx32m $(addprefix --dex-file=,$(filter-out $(DEX2OAT),$^)) --oat=$@ --image=$(TARGET_CORE_IMG) --base=$(IMG_TARGET_BASE_ADDRESS) --host-prefix=$(PRODUCT_OUT)
########################################################################
# The full system boot classpath
@@ -62,4 +62,4 @@
# TODO: change DEX2OATD to order-only prerequisite when output is stable
$(TARGET_BOOT_OAT): $(TARGET_BOOT_DEX) $(DEX2OAT)
@echo "target dex2oat: $@ ($<)"
- $(hide) $(DEX2OAT) -Xms256m -Xmx256m $(addprefix --dex-file=,$(filter-out $(DEX2OAT),$^)) --oat=$@ --image=$(TARGET_BOOT_IMG) --base=$(IMG_TARGET_BASE_ADDRESS) --strip-prefix=$(PRODUCT_OUT)
+ $(hide) $(DEX2OAT) -Xms256m -Xmx256m $(addprefix --dex-file=,$(filter-out $(DEX2OAT),$^)) --oat=$@ --image=$(TARGET_BOOT_IMG) --base=$(IMG_TARGET_BASE_ADDRESS) --host-prefix=$(PRODUCT_OUT)
diff --git a/build/Android.oattest.mk b/build/Android.oattest.mk
index ce615b2..b3dee96 100644
--- a/build/Android.oattest.mk
+++ b/build/Android.oattest.mk
@@ -40,7 +40,7 @@
# TODO: change DEX2OATD (and perhaps $(2) boot oat) to order-only prerequisite when output is stable
$(patsubst %.apk,%.oat,$(patsubst %.jar,%.oat,$(1))): $(1) $(2) $(DEX2OAT)
@echo "target dex2oat: $$@ ($$<)"
- $(hide) $(DEX2OAT) -Xms16m -Xmx16m $(addprefix --boot-dex-file=,$(3)) --boot-oat=$(2) --boot-image=$(patsubst %.oat,%.art,$(2)) $(addprefix --dex-file=,$$<) --oat=$$@ --image=$$(patsubst %.oat,%.art,$$@) --strip-prefix=$(PRODUCT_OUT)
+ $(hide) $(DEX2OAT) -Xms16m -Xmx16m --boot-image=$(patsubst %.oat,%.art,$(2)) $(addprefix --dex-file=,$$<) --oat=$$@ --image=$$(patsubst %.oat,%.art,$$@) --host-prefix=$(PRODUCT_OUT)
endef
########################################################################
@@ -64,7 +64,7 @@
test-art-target-oat-$(1): test-art-target-sync
adb shell touch /sdcard/test-art-target-oat-$(1)
adb shell rm /sdcard/test-art-target-oat-$(1)
- adb shell sh -c "oatexecd -Xbootclasspath:/system/framework/core.jar -Xbootoat:/system/framework/core.oat -Xbootimage:/system/framework/core.art -classpath /system/framework/art-test-dex-$(1).jar -Xoat:/system/framework/art-test-dex-$(1).oat -Ximage:/system/framework/art-test-dex-$(1).art $(1) $(2) && touch /sdcard/test-art-target-oat-$(1)"
+ adb shell sh -c "oatexecd -Ximage:/system/framework/core.art -classpath /system/framework/art-test-dex-$(1).jar -Ximage:/system/framework/art-test-dex-$(1).art $(1) $(2) && touch /sdcard/test-art-target-oat-$(1)"
$(hide) (adb pull /sdcard/test-art-target-oat-$(1) /tmp/ && echo test-art-target-oat-$(1) PASSED) || (echo test-art-target-oat-$(1) FAILED && exit 1)
$(hide) rm /tmp/test-art-target-oat-$(1)
diff --git a/oat_process/app_main.cpp b/oat_process/app_main.cpp
index 9ccdf16..c5ec8e9 100644
--- a/oat_process/app_main.cpp
+++ b/oat_process/app_main.cpp
@@ -212,9 +212,9 @@
// TODO: remove Calculator special case
int oatArgc = argc + 2;
const char* oatArgv[oatArgc];
- if (strcmp(argv[0], "-Xbootimage:/system/framework/boot.oat") != 0) {
+ if (strcmp(argv[0], "-Ximage:/system/framework/boot.oat") != 0) {
LOG(INFO) << "Adding oat arguments";
- oatArgv[0] = "-Xbootimage:/system/framework/boot.oat";
+ oatArgv[0] = "-Ximage:/system/framework/boot.oat";
oatArgv[1] = "-Ximage:/system/app/Calculator.oat";
setenv("CLASSPATH", "/system/app/Calculator.apk", 1);
memcpy(oatArgv + (oatArgc - argc), argv, argc * sizeof(*argv));
diff --git a/src/class_linker.cc b/src/class_linker.cc
index b4e332d..d3a6ed0 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -16,10 +16,12 @@
#include "intern_table.h"
#include "logging.h"
#include "monitor.h"
+#include "oat_file.h"
#include "object.h"
#include "runtime.h"
#include "ScopedLocalRef.h"
#include "space.h"
+#include "stl_util.h"
#include "thread.h"
#include "UniquePtr.h"
#include "utils.h"
@@ -177,17 +179,17 @@
DISALLOW_COPY_AND_ASSIGN(ObjectLock);
};
-ClassLinker* ClassLinker::Create(const std::vector<const DexFile*>& boot_class_path,
- const std::vector<const DexFile*>& class_path,
- InternTable* intern_table, bool image) {
+ClassLinker* ClassLinker::Create(const std::string& boot_class_path,
+ InternTable* intern_table) {
CHECK_NE(boot_class_path.size(), 0U);
UniquePtr<ClassLinker> class_linker(new ClassLinker(intern_table));
- if (image) {
- class_linker->InitFromImage(boot_class_path, class_path);
- } else {
- class_linker->Init(boot_class_path, class_path);
- }
- // TODO: check for failure during initialization
+ class_linker->Init(boot_class_path);
+ return class_linker.release();
+}
+
+ClassLinker* ClassLinker::Create(InternTable* intern_table) {
+ UniquePtr<ClassLinker> class_linker(new ClassLinker(intern_table));
+ class_linker->InitFromImage();
return class_linker.release();
}
@@ -201,8 +203,19 @@
CHECK_EQ(arraysize(class_roots_descriptors_), size_t(kClassRootsMax));
}
-void ClassLinker::Init(const std::vector<const DexFile*>& boot_class_path,
- const std::vector<const DexFile*>& class_path) {
+void CreateClassPath(const std::string& class_path,
+ std::vector<const DexFile*>& class_path_vector) {
+ std::vector<std::string> parsed;
+ Split(class_path, ':', parsed);
+ for (size_t i = 0; i < parsed.size(); ++i) {
+ const DexFile* dex_file = DexFile::Open(parsed[i], Runtime::Current()->GetHostPrefix());
+ if (dex_file != NULL) {
+ class_path_vector.push_back(dex_file);
+ }
+ }
+}
+
+void ClassLinker::Init(const std::string& boot_class_path) {
const Runtime* runtime = Runtime::Current();
if (runtime->IsVerboseStartup()) {
LOG(INFO) << "ClassLinker::InitFrom entering";
@@ -290,16 +303,13 @@
// setup boot_class_path_ and register class_path now that we can
// use AllocObjectArray to create DexCache instances
- for (size_t i = 0; i != boot_class_path.size(); ++i) {
- const DexFile* dex_file = boot_class_path[i];
+ std::vector<const DexFile*> boot_class_path_vector;
+ CreateClassPath(boot_class_path, boot_class_path_vector);
+ for (size_t i = 0; i != boot_class_path_vector.size(); ++i) {
+ const DexFile* dex_file = boot_class_path_vector[i];
CHECK(dex_file != NULL);
AppendToBootClassPath(*dex_file);
}
- for (size_t i = 0; i != class_path.size(); ++i) {
- const DexFile* dex_file = class_path[i];
- CHECK(dex_file != NULL);
- RegisterDexFile(*dex_file);
- }
// Constructor, Field, and Method are necessary so that FindClass can link members
Class* java_lang_reflect_Constructor = AllocClass(java_lang_Class, sizeof(MethodClass));
@@ -523,6 +533,36 @@
}
}
+OatFile* ClassLinker::OpenOat(const Space* space) {
+ const Runtime* runtime = Runtime::Current();
+ if (runtime->IsVerboseStartup()) {
+ LOG(INFO) << "ClassLinker::OpenOat entering";
+ }
+ const ImageHeader& image_header = space->GetImageHeader();
+ String* oat_location = image_header.GetImageRoot(ImageHeader::kOatLocation)->AsString();
+ std::string oat_filename;
+ oat_filename += runtime->GetHostPrefix();
+ oat_filename += oat_location->ToModifiedUtf8();
+ OatFile* oat_file = OatFile::Open(std::string(oat_filename), "", image_header.GetOatBaseAddr());
+ if (oat_file == NULL) {
+ LOG(ERROR) << "Failed to open oat file " << oat_filename << " referenced from image";
+ return NULL;
+ }
+ uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum();
+ uint32_t image_oat_checksum = image_header.GetOatChecksum();
+ if (oat_checksum != image_oat_checksum) {
+ LOG(ERROR) << "Failed to match oat filechecksum " << std::hex << oat_checksum
+ << " to expected oat checksum " << std::hex << oat_checksum
+ << " in image";
+ return NULL;
+ }
+ oat_files_.push_back(oat_file);
+ if (runtime->IsVerboseStartup()) {
+ LOG(INFO) << "ClassLinker::OpenOat exiting";
+ }
+ return oat_file;
+}
+
struct ClassLinker::InitFromImageCallbackState {
ClassLinker* class_linker;
@@ -530,19 +570,47 @@
typedef std::tr1::unordered_map<std::string, ClassRoot> Table;
Table descriptor_to_class_root;
-
- typedef std::tr1::unordered_set<DexCache*, DexCacheHash> Set;
- Set dex_caches;
};
-void ClassLinker::InitFromImage(const std::vector<const DexFile*>& boot_class_path,
- const std::vector<const DexFile*>& class_path) {
+void ClassLinker::InitFromImage() {
const Runtime* runtime = Runtime::Current();
if (runtime->IsVerboseStartup()) {
LOG(INFO) << "ClassLinker::InitFromImage entering";
}
CHECK(!init_done_);
+ const std::vector<Space*>& spaces = Heap::GetSpaces();
+ for (size_t i = 0; i < spaces.size(); i++) {
+ Space* space = spaces[i] ;
+ if (space->IsImageSpace()) {
+ OatFile* oat_file = OpenOat(space);
+ CHECK(oat_file != NULL) << "Failed to open oat file for image";
+ Object* dex_caches_object = space->GetImageHeader().GetImageRoot(ImageHeader::kDexCaches);
+ ObjectArray<DexCache>* dex_caches = dex_caches_object->AsObjectArray<DexCache>();
+
+ CHECK_EQ(oat_file->GetOatHeader().GetDexFileCount(),
+ static_cast<uint32_t>(dex_caches->GetLength()));
+ for (int i = 0; i < dex_caches->GetLength(); i++) {
+ DexCache* dex_cache = dex_caches->Get(i);
+ const std::string& dex_file_location = dex_cache->GetLocation()->ToModifiedUtf8();
+
+ std::string dex_filename;
+ dex_filename += runtime->GetHostPrefix();
+ dex_filename += dex_file_location;
+ const DexFile* dex_file = DexFile::Open(dex_filename, runtime->GetHostPrefix());
+ if (dex_file == NULL) {
+ LOG(FATAL) << "Failed to open dex file " << dex_filename
+ << " referenced from oat file as " << dex_file_location;
+ }
+
+ const OatFile::OatDexFile& oat_dex_file = oat_file->GetOatDexFile(dex_file_location);
+ CHECK_EQ(dex_file->GetHeader().checksum_, oat_dex_file.GetDexFileChecksum());
+
+ RegisterDexFile(*dex_file, dex_cache);
+ }
+ }
+ }
+
HeapBitmap* heap_bitmap = Heap::GetLiveBits();
DCHECK(heap_bitmap != NULL);
@@ -568,36 +636,6 @@
array_interfaces_ = GetClassRoot(kObjectArrayClass)->GetInterfaces();
DCHECK(array_interfaces_ == GetClassRoot(kBooleanArrayClass)->GetInterfaces());
- // build a map from location to DexCache to match up with DexFile::GetLocation
- std::tr1::unordered_map<std::string, DexCache*> location_to_dex_cache;
- typedef InitFromImageCallbackState::Set::const_iterator It; // TODO: C++0x auto
- for (It it = state.dex_caches.begin(), end = state.dex_caches.end(); it != end; ++it) {
- DexCache* dex_cache = *it;
- std::string location = dex_cache->GetLocation()->ToModifiedUtf8();
- location_to_dex_cache[location] = dex_cache;
- }
- CHECK(boot_class_path.size() + class_path.size() == location_to_dex_cache.size())
- << "(" << boot_class_path.size() << " + " << class_path.size()
- << " != " << location_to_dex_cache.size() << ")";
-
- // reinit boot_class_path with DexFile arguments and found DexCaches
- for (size_t i = 0; i != boot_class_path.size(); ++i) {
- const DexFile* dex_file = boot_class_path[i];
- CHECK(dex_file != NULL);
- DexCache* dex_cache = location_to_dex_cache[dex_file->GetLocation()];
- CHECK(dex_cache != NULL) << dex_file->GetLocation();
- AppendToBootClassPath(*dex_file, dex_cache);
- }
-
- // register class_path with DexFile arguments and found DexCaches
- for (size_t i = 0; i != class_path.size(); ++i) {
- const DexFile* dex_file = class_path[i];
- CHECK(dex_file != NULL);
- DexCache* dex_cache = location_to_dex_cache[dex_file->GetLocation()];
- CHECK(dex_cache != NULL) << dex_file->GetLocation();
- RegisterDexFile(*dex_file, dex_cache);
- }
-
String::SetClass(GetClassRoot(kJavaLangString));
Field::SetClass(GetClassRoot(kJavaLangReflectField));
Method::SetClasses(GetClassRoot(kJavaLangReflectConstructor), GetClassRoot(kJavaLangReflectMethod));
@@ -644,14 +682,6 @@
// restore class to ClassLinker::classes_ table
state->class_linker->InsertClass(descriptor, klass);
- // note DexCache to match with DexFile later
- DexCache* dex_cache = klass->GetDexCache();
- if (dex_cache != NULL) {
- state->dex_caches.insert(dex_cache);
- } else {
- DCHECK(klass->IsArrayClass() || klass->IsPrimitive());
- }
-
// 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);
@@ -696,6 +726,8 @@
ShortArray::ResetArrayClass();
PathClassLoader::ResetClass();
StackTraceElement::ResetClass();
+ STLDeleteElements(&boot_class_path_);
+ STLDeleteElements(&oat_files_);
}
DexCache* ClassLinker::AllocDexCache(const DexFile& dex_file) {
diff --git a/src/class_linker.h b/src/class_linker.h
index 3c483a9..747a6e4 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -25,6 +25,7 @@
#include "heap.h"
#include "macros.h"
#include "mutex.h"
+#include "oat_file.h"
#include "object.h"
#include "unordered_map.h"
#include "unordered_set.h"
@@ -39,10 +40,11 @@
class ClassLinker {
public:
- // Initializes the class linker using DexFiles and an optional an image.
- static ClassLinker* Create(const std::vector<const DexFile*>& boot_class_path,
- const std::vector<const DexFile*>& class_path,
- InternTable* intern_table, bool image);
+ // Creates the class linker by boot strapping from dex files.
+ static ClassLinker* Create(const std::string& boot_class_path, InternTable* intern_table);
+
+ // Creates the class linker from one or more images.
+ static ClassLinker* Create(InternTable* intern_table);
~ClassLinker();
@@ -191,13 +193,12 @@
private:
ClassLinker(InternTable*);
- // Initialize class linker from DexFile instances.
- void Init(const std::vector<const DexFile*>& boot_class_path_,
- const std::vector<const DexFile*>& class_path_);
+ // Initialize class linker by bootstraping from dex files
+ void Init(const std::string& boot_class_path);
- // Initialize class linker from pre-initialized image.
- void InitFromImage(const std::vector<const DexFile*>& boot_class_path_,
- const std::vector<const DexFile*>& class_path_);
+ // Initialize class linker from one or more images.
+ void InitFromImage();
+ OatFile* OpenOat(const Space* space);
static void InitFromImageCallback(Object* obj, void* arg);
struct InitFromImageCallbackState;
@@ -298,9 +299,16 @@
void CreateReferenceOffsets(Class *klass, bool instance,
uint32_t reference_offsets);
+ // For use by ImageWriter to find DexCaches for its roots
+ const std::vector<DexCache*>& GetDexCaches() {
+ return dex_caches_;
+ }
+
// lock to protect ClassLinker state
mutable Mutex lock_;
+ std::vector<const OatFile*> oat_files_;
+
std::vector<const DexFile*> boot_class_path_;
std::vector<const DexFile*> dex_files_;
@@ -389,6 +397,7 @@
friend class ObjectTest;
FRIEND_TEST(ObjectTest, AllocObjectArray);
FRIEND_TEST(ExceptionTest, FindExceptionHandler);
+ friend class ImageWriter; // for GetDexCaches
DISALLOW_COPY_AND_ASSIGN(ClassLinker);
};
diff --git a/src/common_test.h b/src/common_test.h
index a7c5ea8..b321071 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -43,7 +43,7 @@
file.reset();
// read dex file
- const DexFile* dex_file = DexFile::OpenFile(location, location, "");
+ const DexFile* dex_file = DexFile::Open(location, "");
CHECK(dex_file != NULL);
return dex_file;
}
@@ -114,10 +114,12 @@
java_lang_dex_file_.reset(GetLibCoreDex());
- boot_class_path_.push_back(java_lang_dex_file_.get());
+ std::string boot_class_path;
+ boot_class_path += "-Xbootclasspath:";
+ boot_class_path += GetLibCoreDexFileName();
Runtime::Options options;
- options.push_back(std::make_pair("bootclasspath", &boot_class_path_));
+ options.push_back(std::make_pair(boot_class_path.c_str(), reinterpret_cast<void*>(NULL)));
options.push_back(std::make_pair("-Xcheck:jni", reinterpret_cast<void*>(NULL)));
options.push_back(std::make_pair("-Xms64m", reinterpret_cast<void*>(NULL)));
options.push_back(std::make_pair("-Xmx64m", reinterpret_cast<void*>(NULL)));
@@ -193,7 +195,7 @@
const DexFile* GetLibCoreDex() {
std::string libcore_dex_file_name = GetLibCoreDexFileName();
- return DexFile::OpenZip(libcore_dex_file_name, "");
+ return DexFile::Open(libcore_dex_file_name, "");
}
uint32_t FindTypeIdxByDescriptor(const DexFile& dex_file, const StringPiece& descriptor) {
@@ -239,7 +241,7 @@
filename += "/system/framework/art-test-dex-";
filename += name;
filename += ".jar";
- const DexFile* dex_file = DexFile::OpenZip(filename, "");
+ const DexFile* dex_file = DexFile::Open(filename, "");
CHECK(dex_file != NULL) << "Failed to open " << filename;
return dex_file;
}
diff --git a/src/dex2oat.cc b/src/dex2oat.cc
index 78d3628..d34a681 100644
--- a/src/dex2oat.cc
+++ b/src/dex2oat.cc
@@ -42,25 +42,14 @@
" --boot-image=<file.art>: provide the image file for the boot class path.\n"
" Example: --boot-image=/system/framework/boot.art\n"
"\n");
- // TODO: remove this by inferring from --boot-image
- fprintf(stderr,
- " --boot-oat=<file.oat>: provide the oat file for the boot class path.\n"
- " Example: --boot-oat=/system/framework/boot.oat\n"
- "\n");
- // TODO: remove this by inderring from --boot-image or --boot-oat
- fprintf(stderr,
- " --boot-dex-file=<dex-file>: specifies a .dex file that is part of the boot\n"
- " image specified with --boot. \n"
- " Example: --boot-dex-file=/system/framework/core.jar\n"
- "\n");
fprintf(stderr,
" --method may be used to limit compilation to a subset of methods.\n"
" Example: --method=Ljava/lang/Object;<init>()V\n"
"\n");
fprintf(stderr,
- " --strip-prefix may be used to strip a path prefix from dex file names in the\n"
- " the generated image to match the target file system layout.\n"
- " Example: --strip-prefix=out/target/product/crespo\n"
+ " --host-prefix may be used to translate host paths to target paths during\n"
+ " cross compilation.\n"
+ " Example: --host-prefix=out/target/product/crespo\n"
"\n");
fprintf(stderr,
" -Xms<n> may be used to specify an initial heap size for the runtime used to\n"
@@ -90,10 +79,8 @@
std::string oat_filename;
const char* image_filename = NULL;
std::string boot_image_option;
- std::string boot_oat_option;
- std::vector<const char*> boot_dex_filenames;
uintptr_t image_base = 0;
- std::string strip_location_prefix;
+ std::string host_prefix;
const char* Xms = NULL;
const char* Xmx = NULL;
@@ -118,17 +105,10 @@
} else if (option.starts_with("--boot-image=")) {
const char* boot_image_filename = option.substr(strlen("--boot-image=")).data();
boot_image_option.clear();
- boot_image_option += "-Xbootimage:";
+ boot_image_option += "-Ximage:";
boot_image_option += boot_image_filename;
- } else if (option.starts_with("--boot-oat=")) {
- const char* boot_oat_filename = option.substr(strlen("--boot-oat=")).data();
- boot_oat_option.clear();
- boot_oat_option += "-Xbootoat:";
- boot_oat_option += boot_oat_filename;
- } else if (option.starts_with("--boot-dex-file=")) {
- boot_dex_filenames.push_back(option.substr(strlen("--boot-dex-file=")).data());
- } else if (option.starts_with("--strip-prefix=")) {
- strip_location_prefix = option.substr(strlen("--strip-prefix=")).data();
+ } else if (option.starts_with("--host-prefix=")) {
+ host_prefix = option.substr(strlen("--host-prefix=")).data();
} else if (option.starts_with("-Xms")) {
Xms = option.data();
} else if (option.starts_with("-Xmx")) {
@@ -154,36 +134,25 @@
return EXIT_FAILURE;
}
- if (boot_image_option.empty() != boot_oat_option.empty()) {
- fprintf(stderr, "--boot-image and --boat-oat must be specified together or not at all\n");
- return EXIT_FAILURE;
- }
-
if (boot_image_option.empty()) {
if (image_base == 0) {
fprintf(stderr, "non-zero --base not specified\n");
return EXIT_FAILURE;
}
- } else {
- if (boot_dex_filenames.empty()) {
- fprintf(stderr, "no --boot-dex-file values specified with --boot-image\n");
- return EXIT_FAILURE;
- }
}
- std::vector<const DexFile*> dex_files;
- DexFile::OpenDexFiles(dex_filenames, dex_files, strip_location_prefix);
-
- std::vector<const DexFile*> boot_dex_files;
- DexFile::OpenDexFiles(boot_dex_filenames, boot_dex_files, strip_location_prefix);
-
Runtime::Options options;
+ std::string boot_class_path_string;
if (boot_image_option.empty()) {
- options.push_back(std::make_pair("bootclasspath", &dex_files));
+ boot_class_path_string += "-Xbootclasspath:";
+ for (size_t i = 0; i < dex_filenames.size()-1; i++) {
+ boot_class_path_string += dex_filenames[i];
+ boot_class_path_string += ":";
+ }
+ boot_class_path_string += dex_filenames[dex_filenames.size()-1];
+ options.push_back(std::make_pair(boot_class_path_string.c_str(), reinterpret_cast<void*>(NULL)));
} else {
- options.push_back(std::make_pair("bootclasspath", &boot_dex_files));
options.push_back(std::make_pair(boot_image_option.c_str(), reinterpret_cast<void*>(NULL)));
- options.push_back(std::make_pair(boot_oat_option.c_str(), reinterpret_cast<void*>(NULL)));
}
if (Xms != NULL) {
options.push_back(std::make_pair(Xms, reinterpret_cast<void*>(NULL)));
@@ -191,6 +160,9 @@
if (Xmx != NULL) {
options.push_back(std::make_pair(Xmx, reinterpret_cast<void*>(NULL)));
}
+ if (!host_prefix.empty()) {
+ options.push_back(std::make_pair("host-prefix", host_prefix.c_str()));
+ }
UniquePtr<Runtime> runtime(Runtime::Create(options, false));
if (runtime.get() == NULL) {
fprintf(stderr, "could not create runtime\n");
@@ -199,10 +171,12 @@
ClassLinker* class_linker = runtime->GetClassLinker();
// If we have an existing boot image, position new space after its oat file
- if (!boot_image_option.empty()) {
- Space* boot_space = Heap::GetBootSpace();
- CHECK(boot_space != NULL);
- byte* oat_limit_addr = boot_space->GetImageHeader().GetOatLimitAddr();
+ if (Heap::GetSpaces().size() > 1) {
+ Space* last_image_space = Heap::GetSpaces()[Heap::GetSpaces().size()-2];
+ CHECK(last_image_space != NULL);
+ CHECK(last_image_space->IsImageSpace());
+ CHECK(!Heap::GetSpaces()[Heap::GetSpaces().size()-1]->IsImageSpace());
+ byte* oat_limit_addr = last_image_space->GetImageHeader().GetOatLimitAddr();
image_base = RoundUp(reinterpret_cast<uintptr_t>(oat_limit_addr), kPageSize);
}
@@ -211,6 +185,8 @@
if (boot_image_option.empty()) {
class_loader = NULL;
} else {
+ std::vector<const DexFile*> dex_files;
+ DexFile::OpenDexFiles(dex_filenames, dex_files, host_prefix);
for (size_t i = 0; i < dex_files.size(); i++) {
class_linker->RegisterDexFile(*dex_files[i]);
}
@@ -279,7 +255,7 @@
}
ImageWriter image_writer;
- if (!image_writer.Write(image_filename, image_base, oat_filename, strip_location_prefix)) {
+ if (!image_writer.Write(image_filename, image_base, oat_filename, host_prefix)) {
fprintf(stderr, "Failed to create image file %s\n", image_filename);
return EXIT_FAILURE;
}
diff --git a/src/dex_file.cc b/src/dex_file.cc
index b4cf837..474d742 100644
--- a/src/dex_file.cc
+++ b/src/dex_file.cc
@@ -59,8 +59,7 @@
const DexFile* DexFile::Open(const std::string& filename,
const std::string& strip_location_prefix) {
if (filename.size() < 4) {
- LOG(WARNING) << "Ignoring short classpath entry '" << filename << "'";
- return NULL;
+ LOG(WARNING) << "Attempting to open dex file with unknown extension '" << filename << "'";
}
std::string suffix(filename.substr(filename.size() - 4));
if (suffix == ".zip" || suffix == ".jar" || suffix == ".apk") {
@@ -106,7 +105,7 @@
}
close(fd);
byte* dex_file = map->GetAddress();
- return Open(dex_file, length, location.ToString(), map.release());
+ return OpenMemory(dex_file, length, location.ToString(), map.release());
}
static const char* kClassesDex = "classes.dex";
@@ -349,8 +348,8 @@
// NOTREACHED
}
-const DexFile* DexFile::Open(const byte* dex_bytes, size_t length,
- const std::string& location, MemMap* mem_map) {
+const DexFile* DexFile::OpenMemory(const byte* dex_bytes, size_t length,
+ const std::string& location, MemMap* mem_map) {
UniquePtr<DexFile> dex_file(new DexFile(dex_bytes, length, location, mem_map));
if (!dex_file->Init()) {
return NULL;
diff --git a/src/dex_file.h b/src/dex_file.h
index cb979ae..45cd33e 100644
--- a/src/dex_file.h
+++ b/src/dex_file.h
@@ -324,19 +324,9 @@
std::vector<const DexFile*>& dex_files,
const std::string& strip_location_prefix);
- // Opens .dex file, guessing the format based on file extension
+ // Opens .dex file, guessing the container format based on file extension
static const DexFile* Open(const std::string& filename,
const std::string& strip_location_prefix);
-
- // Opens a .dex file from the file system.
- static const DexFile* OpenFile(const std::string& filename,
- const std::string& original_location,
- const std::string& strip_location_prefix);
-
- // Opens a .jar, .zip, or .apk file from the file system.
- static const DexFile* OpenZip(const std::string& filename,
- const std::string& strip_location_prefix);
-
// Closes a .dex file.
virtual ~DexFile();
@@ -838,11 +828,21 @@
void ChangePermissions(int prot) const;
private:
+
+ // Opens a .dex file
+ static const DexFile* OpenFile(const std::string& filename,
+ const std::string& original_location,
+ const std::string& strip_location_prefix);
+
+ // Opens a dex file from within a .jar, .zip, or .apk file
+ static const DexFile* OpenZip(const std::string& filename,
+ const std::string& strip_location_prefix);
+
// Opens a .dex file at the given address.
- static const DexFile* Open(const byte* dex_file,
- size_t length,
- const std::string& location,
- MemMap* mem_map);
+ static const DexFile* OpenMemory(const byte* dex_file,
+ size_t length,
+ const std::string& location,
+ MemMap* mem_map);
DexFile(const byte* addr, size_t length, const std::string& location, MemMap* mem_map)
: base_(addr),
diff --git a/src/heap.cc b/src/heap.cc
index 2051051..92ebbd0 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -2,6 +2,7 @@
#include "heap.h"
+#include <limits>
#include <vector>
#include "UniquePtr.h"
@@ -16,8 +17,6 @@
std::vector<Space*> Heap::spaces_;
-Space* Heap::boot_space_ = NULL;
-
Space* Heap::alloc_space_ = NULL;
size_t Heap::maximum_size_ = 0;
@@ -56,29 +55,19 @@
};
void Heap::Init(size_t initial_size, size_t maximum_size,
- const char* boot_image_file_name,
- std::vector<const char*>& image_file_names) {
+ const std::vector<std::string>& image_file_names) {
const Runtime* runtime = Runtime::Current();
if (runtime->IsVerboseStartup()) {
LOG(INFO) << "Heap::Init entering";
}
- Space* boot_space;
- byte* requested_base;
- if (boot_image_file_name == NULL) {
- boot_space = NULL;
- requested_base = NULL;
- } else {
- boot_space = Space::CreateFromImage(boot_image_file_name);
- if (boot_space == NULL) {
- LOG(FATAL) << "Failed to create space from " << boot_image_file_name;
- }
- spaces_.push_back(boot_space);
- byte* oat_limit_addr = boot_space->GetImageHeader().GetOatLimitAddr();
- requested_base = reinterpret_cast<byte*>(RoundUp(reinterpret_cast<uintptr_t>(oat_limit_addr),
- kPageSize));
- }
+ // bounds of all spaces for allocating live and mark bitmaps
+ // there will be at least one space (the alloc space),
+ // so set to base to max and limit to min to start
+ byte* base = reinterpret_cast<byte*>(std::numeric_limits<uintptr_t>::max());
+ byte* limit = reinterpret_cast<byte*>(std::numeric_limits<uintptr_t>::min());
+ byte* requested_base = NULL;
std::vector<Space*> image_spaces;
for (size_t i = 0; i < image_file_names.size(); i++) {
Space* space = Space::CreateFromImage(image_file_names[i]);
@@ -88,20 +77,20 @@
image_spaces.push_back(space);
spaces_.push_back(space);
byte* oat_limit_addr = space->GetImageHeader().GetOatLimitAddr();
- requested_base = reinterpret_cast<byte*>(RoundUp(reinterpret_cast<uintptr_t>(oat_limit_addr),
- kPageSize));
+ if (oat_limit_addr > requested_base) {
+ requested_base = reinterpret_cast<byte*>(RoundUp(reinterpret_cast<uintptr_t>(oat_limit_addr),
+ kPageSize));
+ }
+ base = std::min(base, space->GetBase());
+ limit = std::max(limit, space->GetLimit());
}
Space* space = Space::Create(initial_size, maximum_size, requested_base);
if (space == NULL) {
LOG(FATAL) << "Failed to create alloc space";
}
-
- if (boot_space == NULL) {
- boot_space = space;
- }
- byte* base = std::min(boot_space->GetBase(), space->GetBase());
- byte* limit = std::max(boot_space->GetLimit(), space->GetLimit());
+ base = std::min(base, space->GetBase());
+ limit = std::max(limit, space->GetLimit());
DCHECK_LT(base, limit);
size_t num_bytes = limit - base;
@@ -128,11 +117,7 @@
// TODO: allocate the card table
- // Make objects in boot_space live (after live_bitmap_ is set)
- if (boot_image_file_name != NULL) {
- boot_space_ = boot_space;
- RecordImageAllocations(boot_space);
- }
+ // Make image objects live (after live_bitmap_ is set)
for (size_t i = 0; i < image_spaces.size(); i++) {
RecordImageAllocations(image_spaces[i]);
}
diff --git a/src/heap.h b/src/heap.h
index b669a86..76e33b5 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -41,12 +41,11 @@
typedef void (RootVisitor)(const Object* root, void* arg);
- // Create a heap with the requested sizes. The optional boot image may
- // be NULL, otherwise it is an image filename created by ImageWriter.
- // image_file_names specifies application images to load.
+ // Create a heap with the requested sizes. The possible empty
+ // image_file_names names specify Spaces to load based on
+ // ImageWriter output.
static void Init(size_t starting_size, size_t maximum_size,
- const char* boot_image_file_name,
- std::vector<const char*>& image_file_names);
+ const std::vector<std::string>& image_file_names);
static void Destroy();
@@ -105,10 +104,6 @@
return spaces_;
}
- static Space* GetBootSpace() {
- return boot_space_;
- }
-
static HeapBitmap* GetLiveBits() {
return live_bitmap_;
}
@@ -199,10 +194,6 @@
static std::vector<Space*> spaces_;
- // Space loaded from an image
- // TODO: remove after intern_addr is removed
- static Space* boot_space_;
-
// default Space for allocations
static Space* alloc_space_;
diff --git a/src/image.h b/src/image.h
index 3d2f5f4..4a2efc5 100644
--- a/src/image.h
+++ b/src/image.h
@@ -70,6 +70,7 @@
kAbstractMethodErrorStubArray,
kCalleeSaveMethod,
kOatLocation,
+ kDexCaches,
kImageRootsMax,
};
diff --git a/src/image_test.cc b/src/image_test.cc
index 2fd5c34..903457f 100644
--- a/src/image_test.cc
+++ b/src/image_test.cc
@@ -23,8 +23,8 @@
ImageWriter writer;
ScratchFile tmp_image;
- const uintptr_t image_base = 0x50000000;
- bool success_image = writer.Write(tmp_image.GetFilename(), image_base,
+ const uintptr_t requested_image_base = 0x60000000;
+ bool success_image = writer.Write(tmp_image.GetFilename(), requested_image_base,
std::string(tmp_oat.GetFilename()), "");
ASSERT_TRUE(success_image);
@@ -51,17 +51,10 @@
UniquePtr<const DexFile> dex(GetLibCoreDex());
ASSERT_TRUE(dex.get() != NULL);
- std::vector<const DexFile*> boot_class_path;
- boot_class_path.push_back(dex.get());
-
Runtime::Options options;
- options.push_back(std::make_pair("bootclasspath", &boot_class_path));
- std::string boot_oat("-Xbootoat:");
- boot_oat.append(tmp_oat.GetFilename());
- options.push_back(std::make_pair(boot_oat.c_str(), reinterpret_cast<void*>(NULL)));
- std::string boot_image("-Xbootimage:");
- boot_image.append(tmp_image.GetFilename());
- options.push_back(std::make_pair(boot_image.c_str(), reinterpret_cast<void*>(NULL)));
+ std::string image("-Ximage:");
+ image.append(tmp_image.GetFilename());
+ options.push_back(std::make_pair(image.c_str(), reinterpret_cast<void*>(NULL)));
runtime_.reset(Runtime::Create(options, false));
ASSERT_TRUE(runtime_.get() != NULL);
@@ -70,23 +63,20 @@
ASSERT_TRUE(runtime_->GetJniStubArray() != NULL);
ASSERT_EQ(2U, Heap::GetSpaces().size());
- Space* boot_space = Heap::GetBootSpace();
- ASSERT_TRUE(boot_space != NULL);
+ ASSERT_TRUE(Heap::GetSpaces()[0]->IsImageSpace());
+ ASSERT_FALSE(Heap::GetSpaces()[1]->IsImageSpace());
- // enable to display maps to debug boot_base and boot_limit checking problems below
- if (false) {
- SignalCatcher::HandleSigQuit();
- }
-
- byte* boot_base = boot_space->GetBase();
- byte* boot_limit = boot_space->GetLimit();
+ Space* image_space = Heap::GetSpaces()[0];
+ byte* image_base = image_space->GetBase();
+ byte* image_limit = image_space->GetLimit();
+ CHECK_EQ(requested_image_base, reinterpret_cast<uintptr_t>(image_base));
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);
EXPECT_TRUE(klass != NULL) << descriptor;
- EXPECT_LT(boot_base, reinterpret_cast<byte*>(klass)) << descriptor;
- EXPECT_LT(reinterpret_cast<byte*>(klass), boot_limit) << descriptor;
+ EXPECT_LT(image_base, reinterpret_cast<byte*>(klass)) << descriptor;
+ EXPECT_LT(reinterpret_cast<byte*>(klass), image_limit) << descriptor;
EXPECT_EQ(*klass->GetRawLockWordAddress(), 0); // address should have been removed from monitor
}
}
diff --git a/src/image_writer.cc b/src/image_writer.cc
index 37eac2e..2b2ada4 100644
--- a/src/image_writer.cc
+++ b/src/image_writer.cc
@@ -32,6 +32,7 @@
// currently just write the last space, assuming it is the space that was being used for allocation
CHECK_GE(spaces.size(), 1U);
source_space_ = spaces[spaces.size()-1];
+ CHECK(!source_space_->IsImageSpace());
oat_file_.reset(OatFile::Open(oat_filename, strip_location_prefix, NULL));
if (oat_file_.get() == NULL) {
@@ -114,10 +115,26 @@
}
ObjectArray<Object>* ImageWriter::CreateImageRoots() const {
- // build a Object[] of the roots needed to restore the runtime
Runtime* runtime = Runtime::Current();
ClassLinker* class_linker = runtime->GetClassLinker();
Class* object_array_class = class_linker->FindSystemClass("[Ljava/lang/Object;");
+
+ // build an Object[] of all the DexCaches used in the source_space_
+ const std::vector<DexCache*>& all_dex_caches = class_linker->GetDexCaches();
+ std::vector<DexCache*> source_space_dex_caches;
+ for (size_t i = 0; i < all_dex_caches.size(); i++) {
+ DexCache* dex_cache = all_dex_caches[i];
+ if (InSourceSpace(dex_cache)) {
+ source_space_dex_caches.push_back(dex_cache);
+ }
+ }
+ ObjectArray<Object>* dex_caches = ObjectArray<Object>::Alloc(object_array_class,
+ source_space_dex_caches.size());
+ for (size_t i = 0; i < source_space_dex_caches.size(); i++) {
+ dex_caches->Set(i, source_space_dex_caches[i]);
+ }
+
+ // build an Object[] of the roots needed to restore the runtime
ObjectArray<Object>* image_roots = ObjectArray<Object>::Alloc(object_array_class,
ImageHeader::kImageRootsMax);
image_roots->Set(ImageHeader::kJniStubArray,
@@ -128,6 +145,8 @@
runtime->GetCalleeSaveMethod());
image_roots->Set(ImageHeader::kOatLocation,
String::AllocFromModifiedUtf8(oat_file_->GetLocation().c_str()));
+ image_roots->Set(ImageHeader::kDexCaches,
+ dex_caches);
for (int i = 0; i < ImageHeader::kImageRootsMax; i++) {
CHECK(image_roots->Get(i) != NULL);
}
diff --git a/src/image_writer.h b/src/image_writer.h
index 8c4b308..fda33fe 100644
--- a/src/image_writer.h
+++ b/src/image_writer.h
@@ -62,12 +62,12 @@
object->monitor_ = 0;
}
- bool InSourceSpace(const Object* object) {
+ bool InSourceSpace(const Object* object) const {
DCHECK(source_space_ != NULL);
const byte* o = reinterpret_cast<const byte*>(object);
return (o >= source_space_->GetBase() && o < source_space_->GetLimit());
}
- Object* GetImageAddress(const Object* object) {
+ Object* GetImageAddress(const Object* object) const {
if (object == NULL) {
return NULL;
}
@@ -77,7 +77,7 @@
}
return reinterpret_cast<Object*>(image_base_ + GetImageOffset(object));
}
- Object* GetLocalAddress(const Object* object) {
+ Object* GetLocalAddress(const Object* object) const {
size_t offset = GetImageOffset(object);
byte* dst = image_->GetAddress() + offset;
return reinterpret_cast<Object*>(dst);
diff --git a/src/oat_file.cc b/src/oat_file.cc
index 6266494..15221a6 100644
--- a/src/oat_file.cc
+++ b/src/oat_file.cc
@@ -123,10 +123,10 @@
return mem_map_->GetLimit();
}
-const OatFile::OatDexFile& OatFile::GetOatDexFile(const DexFile& dex_file) {
- Table::const_iterator it = oat_dex_files_.find(dex_file.GetLocation());
+const OatFile::OatDexFile& OatFile::GetOatDexFile(const std::string& dex_file_location) {
+ Table::const_iterator it = oat_dex_files_.find(dex_file_location);
if (it == oat_dex_files_.end()) {
- LOG(FATAL) << "Failed to find OatDexFile for DexFile " << dex_file.GetLocation();
+ LOG(FATAL) << "Failed to find OatDexFile for DexFile " << dex_file_location;
}
return *it->second;
}
diff --git a/src/oat_file.h b/src/oat_file.h
index 2528a6c..6027dda 100644
--- a/src/oat_file.h
+++ b/src/oat_file.h
@@ -51,6 +51,11 @@
class OatDexFile {
public:
const OatClass GetOatClass(uint32_t class_def_index) const;
+
+ uint32_t GetDexFileChecksum() const {
+ return dex_file_checksum_;
+ }
+
~OatDexFile();
private:
OatDexFile(const OatFile* oat_file,
@@ -67,7 +72,7 @@
DISALLOW_COPY_AND_ASSIGN(OatDexFile);
};
- const OatDexFile& GetOatDexFile(const DexFile& dex_file);
+ const OatDexFile& GetOatDexFile(const std::string& dex_file_location);
size_t GetSize() const {
return GetLimit() - GetBase();
diff --git a/src/oat_test.cc b/src/oat_test.cc
index b1453b3..c3d012e 100644
--- a/src/oat_test.cc
+++ b/src/oat_test.cc
@@ -35,7 +35,7 @@
ByteArray* ame_stub_array = runtime->GetAbstractMethodErrorStubArray();
const DexFile& dex_file = *java_lang_dex_file_.get();
- const OatFile::OatDexFile& oat_dex_file = oat_file->GetOatDexFile(dex_file);
+ const OatFile::OatDexFile& oat_dex_file = oat_file->GetOatDexFile(dex_file.GetLocation());
for (size_t i = 0; i < dex_file.NumClassDefs(); i++) {
const DexFile::ClassDef& class_def = dex_file.GetClassDef(i);
const byte* class_data = dex_file.GetClassData(class_def);
diff --git a/src/oatdump.cc b/src/oatdump.cc
index bec8d10..e96b25c 100644
--- a/src/oatdump.cc
+++ b/src/oatdump.cc
@@ -22,43 +22,21 @@
static void usage() {
fprintf(stderr,
"Usage: oatdump [options] ...\n"
- " Example: oatdump --dex-file=$ANDROID_PRODUCT_OUT/system/framework/core.jar --oat=$ANDROID_PRODUCT_OUT/system/framework/boot.oat --image=$ANDROID_PRODUCT_OUT/system/framework/boot.art --strip-prefix=$ANDROID_PRODUCT_OUT\n"
- " Example: adb shell oatdump --dex-file=/system/framework/core.jar --oat=/system/framework/boot.oat --image=/system/framework/boot.art\n"
- "\n");
- // TODO: remove this by inferring from --image or --oat
- fprintf(stderr,
- " --dex-file=<dex-file>: specifies a .dex file location. At least one .dex\n"
- " file must be specified. \n"
- " Example: --dex-file=/system/framework/core.jar\n"
+ " Example: oatdump --image=$ANDROID_PRODUCT_OUT/system/framework/boot.art --host-prefix=$ANDROID_PRODUCT_OUT\n"
+ " Example: adb shell oatdump --image=/system/framework/boot.art\n"
"\n");
fprintf(stderr,
" --image=<file.art>: specifies the required input image filename.\n"
" Example: --image=/system/framework/boot.art\n"
"\n");
- // TODO: remove this by inferring from --image
- fprintf(stderr,
- " --oat=<file.oat>: specifies the required input oat filename.\n"
- " Example: --image=/system/framework/boot.oat\n"
- "\n");
fprintf(stderr,
" --boot-image=<file.art>: provide the image file for the boot class path.\n"
" Example: --boot-image=/system/framework/boot.art\n"
"\n");
- // TODO: remove this by inferring from --boot-image
fprintf(stderr,
- " --boot-oat=<file.oat>: provide the oat file for the boot class path.\n"
- " Example: --boot-oat=/system/framework/boot.oat\n"
- "\n");
- // TODO: remove this by inderring from --boot-image or --boot-oat
- fprintf(stderr,
- " --boot-dex-file=<dex-file>: specifies a .dex file that is part of the boot\n"
- " image specified with --boot. \n"
- " Example: --boot-dex-file=/system/framework/core.jar\n"
- "\n");
- fprintf(stderr,
- " --strip-prefix may be used to strip a path prefix from dex file names in the\n"
- " the generated image to match the target file system layout.\n"
- " Example: --strip-prefix=out/target/product/crespo\n"
+ " --host-prefix may be used to translate host paths to target paths during\n"
+ " cross compilation.\n"
+ " Example: --host-prefix=out/target/product/crespo\n"
"\n");
fprintf(stderr,
" --output=<file> may be used to send the output to a file.\n"
@@ -72,6 +50,7 @@
"kAbstractMethodErrorStubArray",
"kCalleeSaveMethod",
"kOatLocation",
+ "kDexCaches",
};
class OatDump {
@@ -369,32 +348,20 @@
usage();
}
- std::vector<const char*> dex_filenames;
const char* image_filename = NULL;
- const char* oat_filename = NULL;
const char* boot_image_filename = NULL;
- const char* boot_oat_filename = NULL;
- std::vector<const char*> boot_dex_filenames;
- std::string strip_location_prefix;
+ std::string host_prefix;
std::ostream* os = &std::cout;
UniquePtr<std::ofstream> out;
for (int i = 0; i < argc; i++) {
const StringPiece option(argv[i]);
- if (option.starts_with("--dex-file=")) {
- dex_filenames.push_back(option.substr(strlen("--dex-file=")).data());
- } else if (option.starts_with("--image=")) {
+ if (option.starts_with("--image=")) {
image_filename = option.substr(strlen("--image=")).data();
- } else if (option.starts_with("--oat=")) {
- oat_filename = option.substr(strlen("--oat=")).data();
} else if (option.starts_with("--boot-image=")) {
boot_image_filename = option.substr(strlen("--boot-image=")).data();
- } else if (option.starts_with("--boot-oat=")) {
- boot_oat_filename = option.substr(strlen("--boot-oat=")).data();
- } else if (option.starts_with("--boot-dex-file=")) {
- boot_dex_filenames.push_back(option.substr(strlen("--boot-dex-file=")).data());
- } else if (option.starts_with("--strip-prefix=")) {
- strip_location_prefix = option.substr(strlen("--strip-prefix=")).data();
+ } else if (option.starts_with("--host-prefix=")) {
+ host_prefix = option.substr(strlen("--host-prefix=")).data();
} else if (option.starts_with("--output=")) {
const char* filename = option.substr(strlen("--output=")).data();
out.reset(new std::ofstream(filename));
@@ -414,69 +381,29 @@
return EXIT_FAILURE;
}
- if (oat_filename == NULL) {
- fprintf(stderr, "--oat file name not specified\n");
- return EXIT_FAILURE;
- }
-
- if (dex_filenames.empty()) {
- fprintf(stderr, "no --dex-file values specified\n");
- return EXIT_FAILURE;
- }
-
- if ((boot_image_filename != NULL) != (boot_oat_filename != NULL)) {
- fprintf(stderr, "--boot-image and --boat-oat must be specified together or not at all\n");
- return EXIT_FAILURE;
- }
-
- if (boot_image_filename != NULL && boot_dex_filenames.empty()) {
- fprintf(stderr, "no --boot-dex-file values specified with --boot\n");
- return EXIT_FAILURE;
- }
-
- std::vector<const DexFile*> dex_files;
- DexFile::OpenDexFiles(dex_filenames, dex_files, strip_location_prefix);
-
- std::vector<const DexFile*> boot_dex_files;
- DexFile::OpenDexFiles(boot_dex_filenames, boot_dex_files, strip_location_prefix);
-
Runtime::Options options;
std::string image_option;
std::string oat_option;
std::string boot_image_option;
std::string boot_oat_option;
- if (boot_image_filename == NULL) {
- // if we don't have multiple images, pass the main one as the boot to match dex2oat
- boot_image_filename = image_filename;
- boot_oat_filename = oat_filename;
- boot_dex_files = dex_files;
- dex_files.clear();
- } else {
- image_option += "-Ximage:";
- image_option += image_filename;
- oat_option += "-Xoat:";
- oat_option += oat_filename;
- options.push_back(std::make_pair("classpath", &dex_files));
- options.push_back(std::make_pair(image_option.c_str(), reinterpret_cast<void*>(NULL)));
- options.push_back(std::make_pair(oat_option.c_str(), reinterpret_cast<void*>(NULL)));
+ if (boot_image_filename != NULL) {
+ boot_image_option += "-Ximage:";
+ boot_image_option += boot_image_filename;
+ options.push_back(std::make_pair(boot_image_option.c_str(), reinterpret_cast<void*>(NULL)));
}
- boot_image_option += "-Xbootimage:";
- boot_image_option += boot_image_filename;
- boot_oat_option += "-Xbootoat:";
- boot_oat_option += boot_oat_filename;
- options.push_back(std::make_pair("bootclasspath", &boot_dex_files));
- options.push_back(std::make_pair(boot_image_option.c_str(), reinterpret_cast<void*>(NULL)));
- options.push_back(std::make_pair(boot_oat_option.c_str(), reinterpret_cast<void*>(NULL)));
+ image_option += "-Ximage:";
+ image_option += image_filename;
+ options.push_back(std::make_pair(image_option.c_str(), reinterpret_cast<void*>(NULL)));
+
+ if (!host_prefix.empty()) {
+ options.push_back(std::make_pair("host-prefix", host_prefix.c_str()));
+ }
UniquePtr<Runtime> runtime(Runtime::Create(options, false));
if (runtime.get() == NULL) {
fprintf(stderr, "could not create runtime\n");
return EXIT_FAILURE;
}
- ClassLinker* class_linker = runtime->GetClassLinker();
- for (size_t i = 0; i < dex_files.size(); i++) {
- class_linker->RegisterDexFile(*dex_files[i]);
- }
Space* image_space = Heap::GetSpaces()[Heap::GetSpaces().size()-2];
CHECK(image_space != NULL);
diff --git a/src/runtime.cc b/src/runtime.cc
index 6cde082..a874464 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -16,7 +16,6 @@
#include "oat_file.h"
#include "signal_catcher.h"
#include "space.h"
-#include "stl_util.h"
#include "thread.h"
#include "thread_list.h"
@@ -53,7 +52,6 @@
// Make sure all other non-daemon threads have terminated, and all daemon threads are suspended.
delete thread_list_;
- STLDeleteElements(&oat_files_);
delete class_linker_;
Heap::Destroy();
delete intern_table_;
@@ -177,22 +175,16 @@
}
}
-void CreateClassPath(const std::string& class_path,
- std::vector<const DexFile*>& class_path_vector) {
- std::vector<std::string> parsed;
- Split(class_path, ':', parsed);
- for (size_t i = 0; i < parsed.size(); ++i) {
- const DexFile* dex_file = DexFile::Open(parsed[i], "");
- if (dex_file != NULL) {
- class_path_vector.push_back(dex_file);
- }
- }
-}
-
Runtime::ParsedOptions* Runtime::ParsedOptions::Create(const Options& options, bool ignore_unrecognized) {
UniquePtr<ParsedOptions> parsed(new ParsedOptions());
- parsed->boot_image_ = NULL;
- parsed->boot_oat_ = NULL;
+ const char* boot_class_path = getenv("BOOTCLASSPATH");
+ if (boot_class_path != NULL) {
+ parsed->boot_class_path_ = getenv("BOOTCLASSPATH");
+ }
+ const char* class_path = getenv("CLASSPATH");
+ if (class_path != NULL) {
+ parsed->class_path_ = getenv("CLASSPATH");
+ }
#ifdef NDEBUG
// -Xcheck:jni is off by default for regular builds...
parsed->check_jni_ = false;
@@ -211,35 +203,11 @@
for (size_t i = 0; i < options.size(); ++i) {
const StringPiece& option = options[i].first;
+ if (false) {
+ LOG(INFO) << "option[" << i << "]=" << option;
+ }
if (option.starts_with("-Xbootclasspath:")) {
- parsed->boot_class_path_string_ = option.substr(strlen("-Xbootclasspath:")).data();
- } else if (option == "bootclasspath") {
- UNIMPLEMENTED(WARNING) << "what should VMRuntime.getBootClassPath return here?";
- const void* dex_vector = options[i].second;
- const std::vector<const DexFile*>* v
- = reinterpret_cast<const std::vector<const DexFile*>*>(dex_vector);
- if (v == NULL) {
- if (ignore_unrecognized) {
- continue;
- }
- // TODO: usage
- LOG(FATAL) << "Failed to parse " << option;
- return NULL;
- }
- parsed->boot_class_path_ = *v;
- } else if (option == "classpath") {
- const void* dex_vector = options[i].second;
- const std::vector<const DexFile*>* v
- = reinterpret_cast<const std::vector<const DexFile*>*>(dex_vector);
- if (v == NULL) {
- if (ignore_unrecognized) {
- continue;
- }
- // TODO: usage
- LOG(FATAL) << "Failed to parse " << option;
- return NULL;
- }
- parsed->class_path_ = *v;
+ parsed->boot_class_path_ = option.substr(strlen("-Xbootclasspath:")).data();
} else if (option == "-classpath" || option == "-cp") {
// TODO: support -Djava.class.path
i++;
@@ -249,17 +217,9 @@
return NULL;
}
const StringPiece& value = options[i].first;
- parsed->class_path_string_ = value.data();
- } else if (option.starts_with("-Xbootimage:")) {
- // TODO: remove and just use -Ximage:
- parsed->boot_image_ = option.substr(strlen("-Xbootimage:")).data();
- } else if (option.starts_with("-Xbootoat:")) {
- // TODO: remove and just use -Xoat:
- parsed->boot_oat_ = option.substr(strlen("-Xbootoat:")).data();
+ parsed->class_path_ = value.data();
} else if (option.starts_with("-Ximage:")) {
parsed->images_.push_back(option.substr(strlen("-Ximage:")).data());
- } else if (option.starts_with("-Xoat:")) {
- parsed->oats_.push_back(option.substr(strlen("-Xoat:")).data());
} else if (option.starts_with("-Xcheck:jni")) {
parsed->check_jni_ = true;
} else if (option.starts_with("-Xms")) {
@@ -311,6 +271,8 @@
parsed->hook_exit_ = reinterpret_cast<void(*)(jint)>(options[i].second);
} else if (option == "abort") {
parsed->hook_abort_ = reinterpret_cast<void(*)()>(options[i].second);
+ } else if (option == "host-prefix") {
+ parsed->host_prefix_ = reinterpret_cast<const char*>(options[i].second);
} else {
if (!ignore_unrecognized) {
// TODO: print usage via vfprintf
@@ -321,38 +283,6 @@
}
}
- // Consider it an error if both bootclasspath and -Xbootclasspath: are supplied.
- // TODO: remove bootclasspath and classpath which are mostly just used by tests?
- if (!parsed->boot_class_path_.empty() && !parsed->boot_class_path_string_.empty()) {
- // TODO: usage
- LOG(FATAL) << "bootclasspath and -Xbootclasspath: are mutually exclusive options.";
- return NULL;
- }
- if (!parsed->class_path_.empty() && !parsed->class_path_string_.empty()) {
- // TODO: usage
- LOG(FATAL) << "bootclasspath and -Xbootclasspath: are mutually exclusive options.";
- return NULL;
- }
- if (parsed->boot_class_path_.empty()) {
- if (parsed->boot_class_path_string_ == NULL) {
- const char* BOOTCLASSPATH = getenv("BOOTCLASSPATH");
- if (BOOTCLASSPATH != NULL) {
- parsed->boot_class_path_string_ = BOOTCLASSPATH;
- }
- }
- CreateClassPath(parsed->boot_class_path_string_, parsed->boot_class_path_);
- }
-
- if (parsed->class_path_.empty()) {
- if (parsed->class_path_string_ == NULL) {
- const char* CLASSPATH = getenv("CLASSPATH");
- if (CLASSPATH != NULL) {
- parsed->class_path_string_ = CLASSPATH;
- }
- }
- CreateClassPath(parsed->class_path_string_, parsed->class_path_);
- }
-
LOG(INFO) << "CheckJNI is " << (parsed->check_jni_ ? "on" : "off");
return parsed.release();
@@ -375,6 +305,9 @@
if (IsVerboseStartup()) {
LOG(INFO) << "Runtime::Start entering";
}
+
+ CHECK(host_prefix_.empty()) << host_prefix_;
+
InitNativeMethods();
Thread::FinishStartup();
@@ -405,7 +338,7 @@
env->CallStaticVoidMethod(c, mid);
}
-bool Runtime::IsStarted() {
+bool Runtime::IsStarted() const {
return started_;
}
@@ -422,8 +355,9 @@
LOG(INFO) << "Runtime::Init -verbose:startup enabled";
}
- boot_class_path_ = options->boot_class_path_string_;
- class_path_ = options->class_path_string_;
+ host_prefix_ = options->host_prefix_;
+ boot_class_path_ = options->boot_class_path_;
+ class_path_ = options->class_path_;
properties_ = options->properties_;
vfprintf_ = options->hook_vfprintf_;
@@ -435,8 +369,7 @@
thread_list_ = new ThreadList(options->IsVerbose("thread"));
intern_table_ = new InternTable;
- Heap::Init(options->heap_initial_size_, options->heap_maximum_size_,
- options->boot_image_, options->images_);
+ Heap::Init(options->heap_initial_size_, options->heap_maximum_size_, options->images_);
BlockSignals();
@@ -448,22 +381,10 @@
// without creating objects.
Thread::Attach(this, "main", false);
- class_linker_ = ClassLinker::Create(options->boot_class_path_,
- options->class_path_,
- intern_table_,
- Heap::GetBootSpace() != NULL);
- if (Heap::GetBootSpace() != NULL) {
- if (!OpenOat(Heap::GetBootSpace(), options->boot_oat_)) {
- LOG(ERROR) << "Failed to open boot oat " << options->boot_oat_;
- return false;
- }
- }
- for (size_t i = 0; i < options->oats_.size(); i++) {
- if (!OpenOat(Heap::GetSpaces()[i+1], options->oats_[i])) {
- LOG(ERROR) << "Failed to open oat " << options->oats_[i];
- return false;
- }
- }
+ CHECK_GE(Heap::GetSpaces().size(), 1U);
+ class_linker_ = ((Heap::GetSpaces()[0]->IsImageSpace())
+ ? ClassLinker::Create(intern_table_)
+ : ClassLinker::Create(options->boot_class_path_, intern_table_));
if (IsVerboseStartup()) {
LOG(INFO) << "Runtime::Init exiting";
@@ -471,49 +392,6 @@
return true;
}
-bool Runtime::OpenOat(const Space* space, const char* oat) {
- if (IsVerboseStartup()) {
- LOG(INFO) << "Runtime::OpenOat entering " << oat;
- }
- // TODO: check in ParsedOptions?
- if (space == NULL) {
- LOG(ERROR) << "oat specified without image";
- return false;
- }
- if (oat == NULL) {
- LOG(ERROR) << "image specified without oat";
- return false;
- }
- const ImageHeader& image_header = space->GetImageHeader();
- String* oat_location = image_header.GetImageRoot(ImageHeader::kOatLocation)->AsString();
- std::string oat_filename = oat_location->ToModifiedUtf8();
- if (!StringPiece(oat).ends_with(oat_filename)) {
- LOG(ERROR) << "oat file name " << oat
- << " does not match value found in image: " << oat_filename;
- return false;
- }
- // TODO: we should be able to just use oat_filename instead of oat
- // if we passed the prefix argument to find it on the host during cross compilation.
- OatFile* oat_file = OatFile::Open(std::string(oat), "", image_header.GetOatBaseAddr());
- if (oat_file == NULL) {
- LOG(ERROR) << "Failed to open oat file " << oat_filename << " referenced from image";
- return false;
- }
- uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum();
- uint32_t image_oat_checksum = image_header.GetOatChecksum();
- if (oat_checksum != image_oat_checksum) {
- LOG(ERROR) << "Failed to match oat filechecksum " << std::hex << oat_checksum
- << " to expected oat checksum " << std::hex << oat_checksum
- << " in image";
- return false;
- }
- oat_files_.push_back(oat_file);
- if (IsVerboseStartup()) {
- LOG(INFO) << "Runtime::OpenOat exiting";
- }
- return true;
-}
-
void Runtime::InitNativeMethods() {
if (IsVerboseStartup()) {
LOG(INFO) << "Runtime::InitNativeMethods entering";
diff --git a/src/runtime.h b/src/runtime.h
index bae5643..bd2c7a2 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -30,7 +30,6 @@
class InternTable;
class JavaVMExt;
class Method;
-class OatFile;
class SignalCatcher;
class String;
class ThreadList;
@@ -45,14 +44,10 @@
// returns null if problem parsing and ignore_unrecognized is false
static ParsedOptions* Create(const Options& options, bool ignore_unrecognized);
- std::string boot_class_path_string_;
- std::vector<const DexFile*> boot_class_path_;
- std::string class_path_string_;
- std::vector<const DexFile*> class_path_;
- const char* boot_image_;
- const char* boot_oat_;
- std::vector<const char*> images_;
- std::vector<const char*> oats_;
+ std::string boot_class_path_;
+ std::string class_path_;
+ std::string host_prefix_;
+ std::vector<std::string> images_;
bool check_jni_;
std::string jni_trace_;
size_t heap_initial_size_;
@@ -79,10 +74,15 @@
return verbose_startup_;
}
+ const std::string& GetHostPrefix() const {
+ CHECK(!IsStarted());
+ return host_prefix_;
+ }
+
// Starts a runtime, which may cause threads to be started and code to run.
void Start();
- bool IsStarted();
+ bool IsStarted() const;
static Runtime* Current() {
return instance_;
@@ -182,13 +182,24 @@
void BlockSignals();
bool Init(const Options& options, bool ignore_unrecognized);
- bool OpenOat(const Space* space, const char* boot_oat_);
void InitNativeMethods();
void RegisterRuntimeNativeMethods(JNIEnv*);
void StartDaemonThreads();
bool verbose_startup_;
+ // 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
+ // /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
+ // files embedded expect paths of dependent files (an image points
+ // to an oat file and an oat files to one or more dex files). These
+ // files contain the expected target path.
+ std::string host_prefix_;
+
std::string boot_class_path_;
std::string class_path_;
std::vector<std::string> properties_;
@@ -202,8 +213,6 @@
ClassLinker* class_linker_;
- std::vector<const OatFile*> oat_files_;
-
SignalCatcher* signal_catcher_;
JavaVMExt* java_vm_;
diff --git a/src/runtime_test.cc b/src/runtime_test.cc
index 66c181b..ce03571 100644
--- a/src/runtime_test.cc
+++ b/src/runtime_test.cc
@@ -27,7 +27,7 @@
options.push_back(std::make_pair(lib_core.c_str(), null));
options.push_back(std::make_pair("-cp", null));
options.push_back(std::make_pair(lib_core.c_str(), null));
- options.push_back(std::make_pair("-Xbootimage:boot_image", null));
+ options.push_back(std::make_pair("-Ximage:boot_image", null));
options.push_back(std::make_pair("-Ximage:image_1", null));
options.push_back(std::make_pair("-Ximage:image_2", null));
options.push_back(std::make_pair("-Xcheck:jni", null));
@@ -37,22 +37,24 @@
options.push_back(std::make_pair("-Dfoo=bar", null));
options.push_back(std::make_pair("-Dbaz=qux", null));
options.push_back(std::make_pair("-verbose:gc,class,jni", null));
+ options.push_back(std::make_pair("host-prefix", "host_prefix"));
options.push_back(std::make_pair("vfprintf", test_vfprintf));
options.push_back(std::make_pair("abort", test_abort));
options.push_back(std::make_pair("exit", test_exit));
UniquePtr<Runtime::ParsedOptions> parsed(Runtime::ParsedOptions::Create(options, false));
ASSERT_TRUE(parsed.get() != NULL);
- EXPECT_EQ(1U, parsed->boot_class_path_.size());
- EXPECT_EQ(1U, parsed->class_path_.size());
- EXPECT_STREQ("boot_image", parsed->boot_image_);
- EXPECT_EQ(2U, parsed->images_.size());
- EXPECT_STREQ("image_1", parsed->images_[0]);
- EXPECT_STREQ("image_2", parsed->images_[1]);
+ EXPECT_EQ(lib_core, parsed->boot_class_path_);
+ EXPECT_EQ(lib_core, parsed->class_path_);
+ EXPECT_EQ(3U, parsed->images_.size());
+ EXPECT_EQ(std::string("boot_image"), parsed->images_[0]);
+ EXPECT_EQ(std::string("image_1"), parsed->images_[1]);
+ EXPECT_EQ(std::string("image_2"), parsed->images_[2]);
EXPECT_EQ(true, parsed->check_jni_);
EXPECT_EQ(2048U, parsed->heap_initial_size_);
EXPECT_EQ(4 * KB, parsed->heap_maximum_size_);
EXPECT_EQ(1 * MB, parsed->stack_size_);
+ EXPECT_EQ("host_prefix", parsed->host_prefix_);
EXPECT_TRUE(test_vfprintf == parsed->hook_vfprintf_);
EXPECT_TRUE(test_exit == parsed->hook_exit_);
EXPECT_TRUE(test_abort == parsed->hook_abort_);
diff --git a/src/space.cc b/src/space.cc
index 09eb0c9..08d758a 100644
--- a/src/space.cc
+++ b/src/space.cc
@@ -24,7 +24,7 @@
}
}
-Space* Space::CreateFromImage(const char* image_file_name) {
+Space* Space::CreateFromImage(const std::string& image_file_name) {
CHECK(image_file_name != NULL);
UniquePtr<Space> space(new Space());
bool success = space->InitFromImage(image_file_name);
@@ -97,13 +97,13 @@
}
-bool Space::InitFromImage(const char* image_file_name) {
+bool Space::InitFromImage(const std::string& image_file_name) {
const Runtime* runtime = Runtime::Current();
if (runtime->IsVerboseStartup()) {
LOG(INFO) << "Space::InitFromImage entering"
<< " image_file_name=" << image_file_name;
}
- UniquePtr<File> file(OS::OpenFile(image_file_name, false));
+ UniquePtr<File> file(OS::OpenFile(image_file_name.c_str(), false));
if (file.get() == NULL) {
LOG(WARNING) << "Failed to open " << image_file_name;
return false;
diff --git a/src/space.h b/src/space.h
index 1536c27..1e2a58b 100644
--- a/src/space.h
+++ b/src/space.h
@@ -23,7 +23,7 @@
static Space* Create(size_t initial_size, size_t maximum_size, byte* requested_base);
// create a Space from an image file. cannot be used for future allocation or collected.
- static Space* CreateFromImage(const char* image);
+ static Space* CreateFromImage(const std::string& image);
~Space();
@@ -51,8 +51,12 @@
return limit_ - base_;
}
+ bool IsImageSpace() const {
+ return (image_header_ != NULL);
+ }
+
const ImageHeader& GetImageHeader() const {
- CHECK(image_header_ != NULL);
+ CHECK(IsImageSpace());
return *image_header_;
}
@@ -78,7 +82,7 @@
void Init(MemMap* map);
// Initializes the space from an image file
- bool InitFromImage(const char* image_file_name);
+ bool InitFromImage(const std::string& image_file_name);
void* CreateMallocSpace(void* base, size_t initial_size, size_t maximum_size);
diff --git a/test/003-omnibus-opcodes/build b/test/003-omnibus-opcodes/build
index bbd392f..c3af10c 100644
--- a/test/003-omnibus-opcodes/build
+++ b/test/003-omnibus-opcodes/build
@@ -26,10 +26,8 @@
zip ${ANDROID_PRODUCT_OUT}/system/framework/test.jar classes.dex
dex2oatd -Xms16m -Xmx16m \
- --boot-dex-file=${ANDROID_PRODUCT_OUT}/system/framework/core.jar \
- --boot-oat=${ANDROID_PRODUCT_OUT}/system/framework/core.oat \
--boot-image=${ANDROID_PRODUCT_OUT}/system/framework/core.art \
--dex-file=${ANDROID_PRODUCT_OUT}/system/framework/test.jar \
--oat=${ANDROID_PRODUCT_OUT}/system/framework/test.oat \
--image=${ANDROID_PRODUCT_OUT}/system/framework/test.art \
- --strip-prefix=${ANDROID_PRODUCT_OUT}
+ --host-prefix=${ANDROID_PRODUCT_OUT}
diff --git a/test/023-many-interfaces/build b/test/023-many-interfaces/build
index 118e178..d0f376c 100644
--- a/test/023-many-interfaces/build
+++ b/test/023-many-interfaces/build
@@ -28,10 +28,8 @@
zip ${ANDROID_PRODUCT_OUT}/system/framework/test.jar classes.dex
dex2oatd -Xms16m -Xmx16m \
- --boot-dex-file=${ANDROID_PRODUCT_OUT}/system/framework/core.jar \
- --boot-oat=${ANDROID_PRODUCT_OUT}/system/framework/core.oat \
--boot-image=${ANDROID_PRODUCT_OUT}/system/framework/core.art \
--dex-file=${ANDROID_PRODUCT_OUT}/system/framework/test.jar \
--oat=${ANDROID_PRODUCT_OUT}/system/framework/test.oat \
--image=${ANDROID_PRODUCT_OUT}/system/framework/test.art \
- --strip-prefix=${ANDROID_PRODUCT_OUT}
+ --host-prefix=${ANDROID_PRODUCT_OUT}
diff --git a/test/056-const-string-jumbo/build b/test/056-const-string-jumbo/build
index c39779b..a780c13 100644
--- a/test/056-const-string-jumbo/build
+++ b/test/056-const-string-jumbo/build
@@ -47,10 +47,8 @@
zip ${ANDROID_PRODUCT_OUT}/system/framework/test.jar classes.dex
dex2oatd -Xms16m -Xmx16m \
- --boot-dex-file=${ANDROID_PRODUCT_OUT}/system/framework/core.jar \
- --boot-oat=${ANDROID_PRODUCT_OUT}/system/framework/core.oat \
--boot-image=${ANDROID_PRODUCT_OUT}/system/framework/core.art \
--dex-file=${ANDROID_PRODUCT_OUT}/system/framework/test.jar \
--oat=${ANDROID_PRODUCT_OUT}/system/framework/test.oat \
--image=${ANDROID_PRODUCT_OUT}/system/framework/test.art \
- --strip-prefix=${ANDROID_PRODUCT_OUT}
+ --host-prefix=${ANDROID_PRODUCT_OUT}
diff --git a/test/085-old-style-inner-class/build b/test/085-old-style-inner-class/build
index 5a1b04c..d3dc15f 100644
--- a/test/085-old-style-inner-class/build
+++ b/test/085-old-style-inner-class/build
@@ -29,10 +29,8 @@
zip ${ANDROID_PRODUCT_OUT}/system/framework/test.jar classes.dex
dex2oatd -Xms16m -Xmx16m \
- --boot-dex-file=${ANDROID_PRODUCT_OUT}/system/framework/core.jar \
- --boot-oat=${ANDROID_PRODUCT_OUT}/system/framework/core.oat \
--boot-image=${ANDROID_PRODUCT_OUT}/system/framework/core.art \
--dex-file=${ANDROID_PRODUCT_OUT}/system/framework/test.jar \
--oat=${ANDROID_PRODUCT_OUT}/system/framework/test.oat \
--image=${ANDROID_PRODUCT_OUT}/system/framework/test.art \
- --strip-prefix=${ANDROID_PRODUCT_OUT}
+ --host-prefix=${ANDROID_PRODUCT_OUT}
diff --git a/test/etc/default-build b/test/etc/default-build
index e31e0ea..0ef8ba8 100755
--- a/test/etc/default-build
+++ b/test/etc/default-build
@@ -29,13 +29,11 @@
zip ${ANDROID_PRODUCT_OUT}/system/framework/test.jar classes.dex
dex2oatd -Xms16m -Xmx16m \
- --boot-dex-file=${ANDROID_PRODUCT_OUT}/system/framework/core.jar \
- --boot-oat=${ANDROID_PRODUCT_OUT}/system/framework/core.oat \
--boot-image=${ANDROID_PRODUCT_OUT}/system/framework/core.art \
--dex-file=${ANDROID_PRODUCT_OUT}/system/framework/test.jar \
--oat=${ANDROID_PRODUCT_OUT}/system/framework/test.oat \
--image=${ANDROID_PRODUCT_OUT}/system/framework/test.art \
- --strip-prefix=${ANDROID_PRODUCT_OUT}
+ --host-prefix=${ANDROID_PRODUCT_OUT}
if [ -r src-ex ]; then
mkdir classes-ex
@@ -51,11 +49,9 @@
mv classes-1.dex classes.dex
dex2oatd -Xms16m -Xmx16m \
- --boot-dex-file=${ANDROID_PRODUCT_OUT}/system/framework/core.jar \
- --boot-oat=${ANDROID_PRODUCT_OUT}/system/framework/core.oat \
--boot-image=${ANDROID_PRODUCT_OUT}/system/framework/core.art \
--dex-file=${ANDROID_PRODUCT_OUT}/system/framework/test-ex.jar \
--oat=${ANDROID_PRODUCT_OUT}/system/framework/test-ex.oat \
--image=${ANDROID_PRODUCT_OUT}/system/framework/test-ex.art \
- --strip-prefix=${ANDROID_PRODUCT_OUT}
+ --host-prefix=${ANDROID_PRODUCT_OUT}
fi
diff --git a/test/etc/push-and-run-test-jar b/test/etc/push-and-run-test-jar
index fd96b6b..0d4e3b4 100755
--- a/test/etc/push-and-run-test-jar
+++ b/test/etc/push-and-run-test-jar
@@ -135,11 +135,7 @@
adb shell cd /data \; dvz -classpath test.jar Main "$@"
else
cmdline="cd /data; oatexecd \
- -Xbootclasspath:/system/framework/core.jar \
- -Xbootoat:/system/framework/core.oat \
- -Xbootimage:/system/framework/core.art \
- -classpath /system/framework/test.jar \
- -Xoat:/system/framework/test.oat \
+ -Ximage:/system/framework/core.art \
-Ximage:/system/framework/test.art Main"
#cmdline="cd /data; dalvikvm $DEX_VERIFY $DEX_OPTIMIZE $DEX_DEBUG \
# $GC_OPTS -cp test.jar -Xint:${INTERP} -ea Main"