dex2oat: Accept .dm files.
And locate primary.vdex in it to do fast verification.
bug: 63920015
Test: 674-HelloWorld-Dm
Change-Id: If920a6c7e4856a047a24bd30b049ef1ee16d7c1f
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 34ba4b3..f21a5a8 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -605,6 +605,7 @@
input_vdex_fd_(-1),
output_vdex_fd_(-1),
input_vdex_file_(nullptr),
+ dm_fd_(-1),
zip_fd_(-1),
image_base_(0U),
image_classes_zip_filename_(nullptr),
@@ -757,6 +758,11 @@
Usage("--oat-fd should not be used with --image");
}
+ if ((input_vdex_fd_ != -1 || !input_vdex_.empty()) &&
+ (dm_fd_ != -1 || !dm_file_location_.empty())) {
+ Usage("An input vdex should not be passed with a .dm file");
+ }
+
if (!parser_options->oat_symbols.empty() &&
parser_options->oat_symbols.size() != oat_filenames_.size()) {
Usage("--oat-file arguments do not match --oat-symbols arguments");
@@ -1176,6 +1182,8 @@
AssignIfExists(args, M::OutputVdexFd, &output_vdex_fd_);
AssignIfExists(args, M::InputVdex, &input_vdex_);
AssignIfExists(args, M::OutputVdex, &output_vdex_);
+ AssignIfExists(args, M::DmFd, &dm_fd_);
+ AssignIfExists(args, M::DmFile, &dm_file_location_);
AssignIfExists(args, M::OatFd, &oat_fd_);
AssignIfExists(args, M::OatLocation, &oat_location_);
AssignIfExists(args, M::Watchdog, &parser_options->watch_dog_enabled);
@@ -1389,6 +1397,42 @@
}
}
+ if (dm_fd_ != -1 || !dm_file_location_.empty()) {
+ std::string error_msg;
+ if (dm_fd_ != -1) {
+ dm_file_.reset(ZipArchive::OpenFromFd(dm_fd_, "DexMetadata", &error_msg));
+ } else {
+ dm_file_.reset(ZipArchive::Open(dm_file_location_.c_str(), &error_msg));
+ }
+ if (dm_file_ == nullptr) {
+ LOG(WARNING) << "Could not open DexMetadata archive " << error_msg;
+ }
+ }
+
+ if (dm_file_ != nullptr) {
+ DCHECK(input_vdex_file_ == nullptr);
+ std::string error_msg;
+ static const char* kDexMetadata = "DexMetadata";
+ std::unique_ptr<ZipEntry> zip_entry(dm_file_->Find(VdexFile::kVdexNameInDmFile, &error_msg));
+ if (zip_entry == nullptr) {
+ LOG(INFO) << "No " << VdexFile::kVdexNameInDmFile << " file in DexMetadata archive. "
+ << "Not doing fast verification.";
+ } else {
+ std::unique_ptr<MemMap> input_file;
+ if (zip_entry->IsUncompressed()) {
+ input_file.reset(zip_entry->MapDirectlyFromFile(VdexFile::kVdexNameInDmFile, &error_msg));
+ } else {
+ input_file.reset(zip_entry->ExtractToMemMap(
+ kDexMetadata, VdexFile::kVdexNameInDmFile, &error_msg));
+ }
+ if (input_file == nullptr) {
+ LOG(WARNING) << "Could not open vdex file in DexMetadata archive: " << error_msg;
+ } else {
+ input_vdex_file_ = std::make_unique<VdexFile>(input_file.release());
+ }
+ }
+ }
+
// Swap file handling
//
// If the swap fd is not -1, we assume this is the file descriptor of an open but unlinked file
@@ -2238,7 +2282,7 @@
}
bool DoEagerUnquickeningOfVdex() const {
- return MayInvalidateVdexMetadata();
+ return MayInvalidateVdexMetadata() && dm_file_ == nullptr;
}
bool LoadProfile() {
@@ -2788,6 +2832,9 @@
std::string input_vdex_;
std::string output_vdex_;
std::unique_ptr<VdexFile> input_vdex_file_;
+ int dm_fd_;
+ std::string dm_file_location_;
+ std::unique_ptr<ZipArchive> dm_file_;
std::vector<const char*> dex_filenames_;
std::vector<const char*> dex_locations_;
int zip_fd_;
diff --git a/dex2oat/dex2oat_options.cc b/dex2oat/dex2oat_options.cc
index a2e2b48..0eecc84 100644
--- a/dex2oat/dex2oat_options.cc
+++ b/dex2oat/dex2oat_options.cc
@@ -86,6 +86,12 @@
.Define("--output-vdex=_")
.WithType<std::string>()
.IntoKey(M::OutputVdex)
+ .Define("--dm-fd=_")
+ .WithType<int>()
+ .IntoKey(M::DmFd)
+ .Define("--dm-file=_")
+ .WithType<std::string>()
+ .IntoKey(M::DmFile)
.Define("--oat-file=_")
.WithType<std::vector<std::string>>().AppendValues()
.IntoKey(M::OatFiles)
diff --git a/dex2oat/dex2oat_options.def b/dex2oat/dex2oat_options.def
index 9362a3d..9a8bdf4 100644
--- a/dex2oat/dex2oat_options.def
+++ b/dex2oat/dex2oat_options.def
@@ -43,6 +43,8 @@
DEX2OAT_OPTIONS_KEY (std::string, InputVdex)
DEX2OAT_OPTIONS_KEY (int, OutputVdexFd)
DEX2OAT_OPTIONS_KEY (std::string, OutputVdex)
+DEX2OAT_OPTIONS_KEY (int, DmFd)
+DEX2OAT_OPTIONS_KEY (std::string, DmFile)
DEX2OAT_OPTIONS_KEY (std::vector<std::string>, OatFiles)
DEX2OAT_OPTIONS_KEY (std::vector<std::string>, OatSymbols)
DEX2OAT_OPTIONS_KEY (int, OatFd)
diff --git a/runtime/vdex_file.h b/runtime/vdex_file.h
index 4e45128..36fe09c 100644
--- a/runtime/vdex_file.h
+++ b/runtime/vdex_file.h
@@ -97,6 +97,9 @@
friend class VdexFile;
};
+ // Note: The file is called "primary" to match the naming with profiles.
+ static const constexpr char* kVdexNameInDmFile = "primary.vdex";
+
typedef uint32_t VdexChecksum;
using QuickeningTableOffsetType = uint32_t;
diff --git a/test/674-HelloWorld-Dm/expected.txt b/test/674-HelloWorld-Dm/expected.txt
new file mode 100644
index 0000000..af5626b
--- /dev/null
+++ b/test/674-HelloWorld-Dm/expected.txt
@@ -0,0 +1 @@
+Hello, world!
diff --git a/test/674-HelloWorld-Dm/info.txt b/test/674-HelloWorld-Dm/info.txt
new file mode 100644
index 0000000..3a769c4
--- /dev/null
+++ b/test/674-HelloWorld-Dm/info.txt
@@ -0,0 +1 @@
+Hello World test with --dm-file passed to dex2oat.
diff --git a/test/674-HelloWorld-Dm/run b/test/674-HelloWorld-Dm/run
new file mode 100644
index 0000000..199ffc3
--- /dev/null
+++ b/test/674-HelloWorld-Dm/run
@@ -0,0 +1,17 @@
+#!/bin/bash
+#
+# Copyright (C) 2018 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.
+
+exec ${RUN} --dm "${@}"
diff --git a/test/674-HelloWorld-Dm/src/Main.java b/test/674-HelloWorld-Dm/src/Main.java
new file mode 100644
index 0000000..1ef6289
--- /dev/null
+++ b/test/674-HelloWorld-Dm/src/Main.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+public class Main {
+ public static void main(String[] args) {
+ System.out.println("Hello, world!");
+ }
+}
diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar
index 5e40b86..fd40ed7 100755
--- a/test/etc/run-test-jar
+++ b/test/etc/run-test-jar
@@ -64,6 +64,7 @@
EXTERNAL_LOG_TAGS="n" # if y respect externally set ANDROID_LOG_TAGS.
DRY_RUN="n" # if y prepare to run the test but don't run it.
TEST_VDEX="n"
+TEST_DM="n"
TEST_IS_NDEBUG="n"
APP_IMAGE="y"
JVMTI_STRESS="n"
@@ -346,6 +347,9 @@
elif [ "x$1" = "x--vdex" ]; then
TEST_VDEX="y"
shift
+ elif [ "x$1" = "x--dm" ]; then
+ TEST_DM="y"
+ shift
elif [ "x$1" = "x--vdex-filter" ]; then
shift
option="$1"
@@ -672,6 +676,7 @@
profman_cmdline="true"
dex2oat_cmdline="true"
vdex_cmdline="true"
+dm_cmdline="true"
mkdir_locations="${mkdir_locations} ${DEX_LOCATION}/dalvik-cache/$ISA"
strip_cmdline="true"
sync_cmdline="true"
@@ -735,6 +740,10 @@
vdex_cmdline="${dex2oat_cmdline} ${VDEX_FILTER} --input-vdex=$DEX_LOCATION/oat/$ISA/$TEST_NAME.vdex --output-vdex=$DEX_LOCATION/oat/$ISA/$TEST_NAME.vdex"
elif [ "$TEST_VDEX" = "y" ]; then
vdex_cmdline="${dex2oat_cmdline} ${VDEX_FILTER} --input-vdex=$DEX_LOCATION/oat/$ISA/$TEST_NAME.vdex"
+ elif [ "$TEST_DM" = "y" ]; then
+ dex2oat_cmdline="${dex2oat_cmdline} --output-vdex=$DEX_LOCATION/oat/$ISA/primary.vdex"
+ dm_cmdline="zip -qj $DEX_LOCATION/oat/$ISA/$TEST_NAME.dm $DEX_LOCATION/oat/$ISA/primary.vdex"
+ vdex_cmdline="${dex2oat_cmdline} --dump-timings --dm-file=$DEX_LOCATION/oat/$ISA/$TEST_NAME.dm"
elif [ "$PROFILE" = "y" ] || [ "$RANDOM_PROFILE" = "y" ]; then
vdex_cmdline="${dex2oat_cmdline} --input-vdex=$DEX_LOCATION/oat/$ISA/$TEST_NAME.vdex --output-vdex=$DEX_LOCATION/oat/$ISA/$TEST_NAME.vdex"
fi
@@ -782,6 +791,7 @@
# Remove whitespace.
dex2oat_cmdline=$(echo $dex2oat_cmdline)
dalvikvm_cmdline=$(echo $dalvikvm_cmdline)
+dm_cmdline=$(echo $dm_cmdline)
vdex_cmdline=$(echo $vdex_cmdline)
profman_cmdline=$(echo $profman_cmdline)
@@ -851,6 +861,7 @@
export PATH=$ANDROID_ROOT/bin:$PATH && \
$profman_cmdline && \
$dex2oat_cmdline && \
+ $dm_cmdline && \
$vdex_cmdline && \
$strip_cmdline && \
$sync_cmdline && \
@@ -927,7 +938,7 @@
fi
if [ "$DEV_MODE" = "y" ]; then
- echo "mkdir -p ${mkdir_locations} && $profman_cmdline && $dex2oat_cmdline && $vdex_cmdline && $strip_cmdline && $sync_cmdline && $cmdline"
+ echo "mkdir -p ${mkdir_locations} && $profman_cmdline && $dex2oat_cmdline && $dm_cmdline && $vdex_cmdline && $strip_cmdline && $sync_cmdline && $cmdline"
fi
cd $ANDROID_BUILD_TOP
@@ -943,6 +954,7 @@
mkdir -p ${mkdir_locations} || exit 1
$profman_cmdline || { echo "Profman failed." >&2 ; exit 2; }
$dex2oat_cmdline || { echo "Dex2oat failed." >&2 ; exit 2; }
+ $dm_cmdline || { echo "Dex2oat failed." >&2 ; exit 2; }
$vdex_cmdline || { echo "Dex2oat failed." >&2 ; exit 2; }
$strip_cmdline || { echo "Strip failed." >&2 ; exit 3; }
$sync_cmdline || { echo "Sync failed." >&2 ; exit 4; }
diff --git a/test/run-test b/test/run-test
index 75fe15c..bca5408 100755
--- a/test/run-test
+++ b/test/run-test
@@ -421,6 +421,9 @@
elif [ "x$1" = "x--vdex" ]; then
run_args="${run_args} --vdex"
shift
+ elif [ "x$1" = "x--dm" ]; then
+ run_args="${run_args} --dm"
+ shift
elif [ "x$1" = "x--vdex-filter" ]; then
shift
filter=$1