Add a new imgdiag tool to diff boot.art/core.art against a process

Analyze the dirty memory pages of a running process per-object,
this allows is to to fine-tune the dirty object binning algorithm in
image writer.

Also:
* Factor out oatdump command line parsing code into cmdline.h
* Factor out common build rules for building variations of binaries
* Add a gtest for imgdiag

Bug: 17611661
Change-Id: I3ac852a0d223af66f6d59ae5dbc3df101475e3d0
diff --git a/build/Android.common.mk b/build/Android.common.mk
index 39e78fa..00962f5 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -14,8 +14,8 @@
 # limitations under the License.
 #
 
-ifndef ANDROID_COMMON_MK
-ANDROID_COMMON_MK = true
+ifndef ART_ANDROID_COMMON_MK
+ART_ANDROID_COMMON_MK = true
 
 ART_TARGET_SUPPORTED_ARCH := arm arm64 mips x86 x86_64
 ART_HOST_SUPPORTED_ARCH := x86 x86_64
@@ -81,4 +81,4 @@
   2ND_ART_HOST_OUT_SHARED_LIBRARIES := $(2ND_HOST_OUT_SHARED_LIBRARIES)
 endif
 
-endif # ANDROID_COMMON_MK
+endif # ART_ANDROID_COMMON_MK
diff --git a/build/Android.common_build.mk b/build/Android.common_build.mk
index 1a8752f..241715e 100644
--- a/build/Android.common_build.mk
+++ b/build/Android.common_build.mk
@@ -14,10 +14,11 @@
 # limitations under the License.
 #
 
-ifndef ANDROID_COMMON_BUILD_MK
-ANDROID_COMMON_BUILD_MK = true
+ifndef ART_ANDROID_COMMON_BUILD_MK
+ART_ANDROID_COMMON_BUILD_MK = true
 
 include art/build/Android.common.mk
+include art/build/Android.common_utils.mk
 
 # These can be overridden via the environment or by editing to
 # enable/disable certain build configuration.
@@ -330,4 +331,4 @@
   ART_BUILD_DEBUG := true
 endif
 
-endif # ANDROID_COMMON_BUILD_MK
+endif # ART_ANDROID_COMMON_BUILD_MK
diff --git a/build/Android.common_path.mk b/build/Android.common_path.mk
index 281d189..e0c0b0c 100644
--- a/build/Android.common_path.mk
+++ b/build/Android.common_path.mk
@@ -14,8 +14,8 @@
 # limitations under the License.
 #
 
-ifndef ANDROID_COMMON_PATH_MK
-ANDROID_COMMON_PATH_MK := true
+ifndef ART_ANDROID_COMMON_PATH_MK
+ART_ANDROID_COMMON_PATH_MK := true
 
 include art/build/Android.common.mk
 
@@ -88,4 +88,4 @@
 
 HOST_CORE_DEX_FILES   := $(foreach jar,$(HOST_CORE_JARS),  $(call intermediates-dir-for,JAVA_LIBRARIES,$(jar),t,COMMON)/javalib.jar)
 TARGET_CORE_DEX_FILES := $(foreach jar,$(TARGET_CORE_JARS),$(call intermediates-dir-for,JAVA_LIBRARIES,$(jar), ,COMMON)/javalib.jar)
-endif # ANDROID_COMMON_PATH_MK
+endif # ART_ANDROID_COMMON_PATH_MK
diff --git a/build/Android.common_test.mk b/build/Android.common_test.mk
index 2493565..0ae42dd 100644
--- a/build/Android.common_test.mk
+++ b/build/Android.common_test.mk
@@ -14,8 +14,8 @@
 # limitations under the License.
 #
 
-ifndef ANDROID_COMMON_TEST_MK
-ANDROID_COMMON_TEST_MK = true
+ifndef ART_ANDROID_COMMON_TEST_MK
+ART_ANDROID_COMMON_TEST_MK = true
 
 include art/build/Android.common_path.mk
 
@@ -197,4 +197,4 @@
   endif
 endef
 
-endif # ANDROID_COMMON_TEST_MK
+endif # ART_ANDROID_COMMON_TEST_MK
diff --git a/build/Android.common_utils.mk b/build/Android.common_utils.mk
new file mode 100644
index 0000000..8069c3a
--- /dev/null
+++ b/build/Android.common_utils.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2014 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_ANDROID_COMMON_UTILS_MK
+ART_ANDROID_COMMON_UTILS_MK = true
+
+#
+# Convert a string into an uppercase string.
+#
+# $(1): a string which should be made uppercase
+art-string-to-uppercase = $(shell echo $(1) | tr '[:lower:]' '[:upper:]')
+
+endif # ART_ANDROID_COMMON_UTILS_MK
diff --git a/build/Android.executable.mk b/build/Android.executable.mk
index be97e82..ef9e7cd 100644
--- a/build/Android.executable.mk
+++ b/build/Android.executable.mk
@@ -47,12 +47,13 @@
   art_target_or_host := $(5)
   art_ndebug_or_debug := $(6)
   art_multilib := $(7)
+  art_out_binary_name :=
 
   include $(CLEAR_VARS)
   LOCAL_CPP_EXTENSION := $(ART_CPP_EXTENSION)
   LOCAL_MODULE_TAGS := optional
   LOCAL_SRC_FILES := $$(art_source)
-  LOCAL_C_INCLUDES += $(ART_C_INCLUDES) art/runtime $$(art_c_includes)
+  LOCAL_C_INCLUDES += $(ART_C_INCLUDES) art/runtime art/cmdline $$(art_c_includes)
   LOCAL_SHARED_LIBRARIES += $$(art_shared_libraries)
   LOCAL_WHOLE_STATIC_LIBRARIES += libsigchain
 
@@ -91,32 +92,114 @@
   endif
 
   LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk
+  LOCAL_ADDITIONAL_DEPENDENCIES += art/build/Android.common_utils.mk
   LOCAL_ADDITIONAL_DEPENDENCIES += art/build/Android.executable.mk
 
   ifeq ($$(art_target_or_host),target)
     LOCAL_MODULE_TARGET_ARCH := $(ART_SUPPORTED_ARCH)
   endif
 
-  # If multilib, need to provide stem.
   LOCAL_MULTILIB := $$(art_multilib)
+  art_out_binary_name := $$(LOCAL_MODULE)
+
+  # If multilib=both (potentially building both 32-bit and 64-bit), need to provide stem.
   ifeq ($$(art_multilib),both)
-    ifeq ($$(art_ndebug_or_debug),ndebug)
-      LOCAL_MODULE_STEM_32 := $$(art_executable)32
-      LOCAL_MODULE_STEM_64 := $$(art_executable)
-    else #debug
-      LOCAL_MODULE_STEM_32 := $$(art_executable)d32
-      LOCAL_MODULE_STEM_64 := $$(art_executable)d
+    # Set up a 32-bit/64-bit stem if we are building both binaries.
+    # In this case, the 32-bit binary has an additional 32-bit suffix.
+    LOCAL_MODULE_STEM_32 := $$(LOCAL_MODULE)32
+    LOCAL_MODULE_STEM_64 := $$(LOCAL_MODULE)
+
+    # Remember the binary names so we can add them to the global art executables list later.
+    art_out_binary_name := $$(LOCAL_MODULE_STEM_32) $$(LOCAL_MODULE_STEM_64)
+
+    # For single-architecture targets, remove any binary name suffixes.
+    ifeq ($$(art_target_or_host),target)
+      ifeq (,$(TARGET_2ND_ARCH))
+        LOCAL_MODULE_STEM_32 := $$(LOCAL_MODULE)
+        art_out_binary_name := $$(LOCAL_MODULE)
+      endif
+    endif
+
+    # For single-architecture hosts, remove any binary name suffixes.
+    ifeq ($$(art_target_or_host),host)
+      ifeq (,$(HOST_2ND_ARCH))
+        LOCAL_MODULE_STEM_32 := $$(LOCAL_MODULE)
+        art_out_binary_name := $$(LOCAL_MODULE)
+      endif
     endif
   endif
 
   include external/libcxx/libcxx.mk
   ifeq ($$(art_target_or_host),target)
     include $(BUILD_EXECUTABLE)
-    ART_TARGET_EXECUTABLES := $(ART_TARGET_EXECUTABLES) $(TARGET_OUT_EXECUTABLES)/$$(LOCAL_MODULE)
+    ART_TARGET_EXECUTABLES := $(ART_TARGET_EXECUTABLES) $$(foreach name,$$(art_out_binary_name),$(TARGET_OUT_EXECUTABLES)/$$(name))
   else # host
     LOCAL_IS_HOST_MODULE := true
     include $(BUILD_HOST_EXECUTABLE)
-    ART_HOST_EXECUTABLES := $(ART_HOST_EXECUTABLES) $(HOST_OUT_EXECUTABLES)/$$(LOCAL_MODULE)
+    ART_HOST_EXECUTABLES := $(ART_HOST_EXECUTABLES) $$(foreach name,$$(art_out_binary_name),$(HOST_OUT_EXECUTABLES)/$$(name))
   endif
 
+  # Clear out local variables now that we're done with them.
+  art_executable :=
+  art_source :=
+  art_shared_libraries :=
+  art_c_includes :=
+  art_target_or_host :=
+  art_ndebug_or_debug :=
+  art_multilib :=
+  art_out_binary_name :=
+
+endef
+
+#
+# Build many art executables from multiple variations (debug/ndebug, host/target, 32/64bit).
+# By default only either 32-bit or 64-bit is built (but not both -- see multilib arg).
+# All other variations are gated by ANDROID_BUILD_(TARGET|HOST)_[N]DEBUG.
+# The result must be eval-uated.
+#
+# $(1): executable name
+# $(2): source files
+# $(3): library dependencies (common); debug prefix is added on as necessary automatically.
+# $(4): library dependencies (target only)
+# $(5): library dependencies (host only)
+# $(6): extra include directories
+# $(7): multilib (default: empty), valid values: {,32,64,both})
+define build-art-multi-executable
+  $(foreach debug_flavor,ndebug debug,
+    $(foreach target_flavor,host target,
+      art-multi-binary-name := $(1)
+      art-multi-source-files := $(2)
+      art-multi-lib-dependencies := $(3)
+      art-multi-lib-dependencies-target := $(4)
+      art-multi-lib-dependencies-host := $(5)
+      art-multi-include-extra := $(6)
+      art-multi-multilib := $(7)
+
+      # Add either -host or -target specific lib dependencies to the lib dependencies.
+      art-multi-lib-dependencies += $$(art-multi-lib-dependencies-$(target_flavor))
+
+      # Replace libart- prefix with libartd- for debug flavor.
+      ifeq ($(debug_flavor),debug)
+        art-multi-lib-dependencies := $$(subst libart-,libartd-,$$(art-multi-lib-dependencies))
+      endif
+
+      # Build the env guard var name, e.g. ART_BUILD_HOST_NDEBUG.
+      art-multi-env-guard := $$(call art-string-to-uppercase,ART_BUILD_$(target_flavor)_$(debug_flavor))
+
+      # Build the art executable only if the corresponding env guard was set.
+      ifeq ($$($$(art-multi-env-guard)),true)
+        $$(eval $$(call build-art-executable,$$(art-multi-binary-name),$$(art-multi-source-files),$$(art-multi-lib-dependencies),$$(art-multi-include-extra),$(target_flavor),$(debug_flavor),$$(art-multi-multilib)))
+      endif
+
+      # Clear locals now they've served their purpose.
+      art-multi-binary-name :=
+      art-multi-source-files :=
+      art-multi-lib-dependencies :=
+      art-multi-lib-dependencies-target :=
+      art-multi-lib-dependencies-host :=
+      art-multi-include-extra :=
+      art-multi-multilib :=
+      art-multi-env-guard :=
+    )
+  )
 endef
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index 5567d15..4c19ba0 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -65,10 +65,15 @@
 # TODO: document why this is needed.
 ART_GTEST_proxy_test_HOST_DEPS := $(HOST_CORE_IMAGE_default_no-pic_64) $(HOST_CORE_IMAGE_default_no-pic_32)
 
+# The imgdiag test has dependencies on core.oat since it needs to load it during the test.
+ART_GTEST_imgdiag_test_HOST_DEPS := $(HOST_CORE_IMAGE_default_no-pic_64) $(HOST_CORE_IMAGE_default_no-pic_32)
+ART_GTEST_imgdiag_test_TARGET_DEPS := $(TARGET_CORE_IMAGE_default_no-pic_64) $(TARGET_CORE_IMAGE_default_no-pic_32)
+
 # The path for which all the source files are relative, not actually the current directory.
 LOCAL_PATH := art
 
 RUNTIME_GTEST_COMMON_SRC_FILES := \
+  imgdiag/imgdiag_test.cc \
   runtime/arch/arch_test.cc \
   runtime/arch/instruction_set_test.cc \
   runtime/arch/instruction_set_features_test.cc \