Merge "ART: Export ASAN_OPTIONS in build testrunner"
diff --git a/build/Android.common_path.mk b/build/Android.common_path.mk
index 4466118..f4f8d49 100644
--- a/build/Android.common_path.mk
+++ b/build/Android.common_path.mk
@@ -74,9 +74,6 @@
TARGET_CORE_IMG_LOCATION := $(ART_TARGET_TEST_OUT)/core.art
# Jar files for core.art.
-TARGET_CORE_JARS := core-oj core-libart conscrypt okhttp bouncycastle apache-xml
-HOST_CORE_JARS := $(addsuffix -hostdex,$(TARGET_CORE_JARS))
-
HOST_CORE_DEX_LOCATIONS := $(foreach jar,$(HOST_CORE_JARS), $(HOST_OUT_JAVA_LIBRARIES)/$(jar).jar)
ifeq ($(ART_TEST_ANDROID_ROOT),)
TARGET_CORE_DEX_LOCATIONS := $(foreach jar,$(TARGET_CORE_JARS),/$(DEXPREOPT_BOOT_JAR_DIR)/$(jar).jar)
diff --git a/test/044-proxy/check b/test/044-proxy/check
new file mode 100755
index 0000000..0cb2c32
--- /dev/null
+++ b/test/044-proxy/check
@@ -0,0 +1,33 @@
+#!/bin/bash
+#
+# Copyright (C) 2017 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.
+
+expected="$1"
+output="$2"
+
+# Jack inserts a synthetic default method for interface methods with covariant return types.
+# Javac does not do this, so we must fiddle with the expected.txt to get the different behavior.
+
+expected_jack_line='Invocation of public default java[.]lang[.]Object NarrowingTest\$I2[.]foo[(][)]'
+replaced_javac_line='Invocation of public abstract java.lang.Object NarrowingTest\$I1.foo()'
+
+expected_replaced="$expected"
+
+if [[ $USE_JACK == false ]]; then
+ expected_replaced="$output.tmp"
+ sed "s:$expected_jack_line:$replaced_javac_line:g" "$expected" > "$expected_replaced"
+fi
+
+diff --strip-trailing-cr -q "$expected_replaced" "$output" >/dev/null
diff --git a/test/551-checker-shifter-operand/build b/test/551-checker-shifter-operand/build
deleted file mode 100644
index 027a0ea..0000000
--- a/test/551-checker-shifter-operand/build
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-# This is an almost exact copy of `art/test/etc/default-build`. Only the parsing
-# of `dx` option has been overriden.
-
-# Stop if something fails.
-set -e
-
-# Set default values for directories.
-if [ -d smali ]; then
- HAS_SMALI=true
-else
- HAS_SMALI=false
-fi
-
-if [ -d src ]; then
- HAS_SRC=true
-else
- HAS_SRC=false
-fi
-
-if [ -d src2 ]; then
- HAS_SRC2=true
-else
- HAS_SRC2=false
-fi
-
-if [ -d src-multidex ]; then
- HAS_SRC_MULTIDEX=true
-else
- HAS_SRC_MULTIDEX=false
-fi
-
-if [ -d src-ex ]; then
- HAS_SRC_EX=true
-else
- HAS_SRC_EX=false
-fi
-
-DX_FLAGS=""
-SKIP_DX_MERGER="false"
-EXPERIMENTAL=""
-
-# Setup experimental flag mappings in a bash associative array.
-declare -A JACK_EXPERIMENTAL_ARGS
-JACK_EXPERIMENTAL_ARGS["default-methods"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24"
-JACK_EXPERIMENTAL_ARGS["lambdas"]="-D jack.java.source.version=1.8 -D jack.android.min-api-level=24"
-
-while true; do
- if [ "x$1" = "x--dx-option" ]; then
- shift
- option="$1"
- # Make sure we run this test *with* `dx` optimizations.
- if [ "x$option" != "x--no-optimize" ]; then
- DX_FLAGS="${DX_FLAGS} $option"
- fi
- shift
- elif [ "x$1" = "x--jvm" ]; then
- shift
- elif [ "x$1" = "x--no-src" ]; then
- HAS_SRC=false
- shift
- elif [ "x$1" = "x--no-src2" ]; then
- HAS_SRC2=false
- shift
- elif [ "x$1" = "x--no-src-multidex" ]; then
- HAS_SRC_MULTIDEX=false
- shift
- elif [ "x$1" = "x--no-src-ex" ]; then
- HAS_SRC_EX=false
- shift
- elif [ "x$1" = "x--no-smali" ]; then
- HAS_SMALI=false
- shift
- elif [ "x$1" = "x--experimental" ]; then
- shift
- EXPERIMENTAL="${EXPERIMENTAL} $1"
- shift
- elif expr "x$1" : "x--" >/dev/null 2>&1; then
- echo "unknown $0 option: $1" 1>&2
- exit 1
- else
- break
- fi
-done
-
-# Add args from the experimental mappings.
-for experiment in ${EXPERIMENTAL}; do
- JACK_ARGS="${JACK_ARGS} ${JACK_EXPERIMENTAL_ARGS[${experiment}]}"
-done
-
-if [ -e classes.dex ]; then
- zip $TEST_NAME.jar classes.dex
- exit 0
-fi
-
-if ! [ "${HAS_SRC}" = "true" ] && ! [ "${HAS_SRC2}" = "true" ]; then
- # No src directory? Then forget about trying to run dx.
- SKIP_DX_MERGER="true"
-fi
-
-if [ "${HAS_SRC_MULTIDEX}" = "true" ]; then
- # Jack does not support this configuration unless we specify how to partition the DEX file
- # with a .jpp file.
- USE_JACK="false"
-fi
-
-if [ ${USE_JACK} = "true" ]; then
- # Jack toolchain
- if [ "${HAS_SRC}" = "true" ]; then
- ${JACK} ${JACK_ARGS} --output-jack src.jack src
- imported_jack_files="--import src.jack"
- fi
-
- if [ "${HAS_SRC2}" = "true" ]; then
- ${JACK} ${JACK_ARGS} --output-jack src2.jack src2
- imported_jack_files="--import src2.jack ${imported_jack_files}"
- fi
-
- # Compile jack files into a DEX file. We set jack.import.type.policy=keep-first to consider
- # class definitions from src2 first.
- if [ "${HAS_SRC}" = "true" ] || [ "${HAS_SRC2}" = "true" ]; then
- ${JACK} ${JACK_ARGS} ${imported_jack_files} -D jack.import.type.policy=keep-first --output-dex .
- fi
-else
- # Legacy toolchain with javac+dx
- if [ "${HAS_SRC}" = "true" ]; then
- mkdir classes
- ${JAVAC} ${JAVAC_ARGS} -implicit:none -classpath src-multidex -d classes `find src -name '*.java'`
- fi
-
- if [ "${HAS_SRC_MULTIDEX}" = "true" ]; then
- mkdir classes2
- ${JAVAC} -implicit:none -classpath src -d classes2 `find src-multidex -name '*.java'`
- if [ ${NEED_DEX} = "true" ]; then
- ${DX} -JXmx256m --debug --dex --dump-to=classes2.lst --output=classes2.dex \
- --dump-width=1000 ${DX_FLAGS} classes2
- fi
- fi
-
- if [ "${HAS_SRC2}" = "true" ]; then
- mkdir -p classes
- ${JAVAC} ${JAVAC_ARGS} -d classes `find src2 -name '*.java'`
- fi
-
- if [ "${HAS_SRC}" = "true" ] || [ "${HAS_SRC2}" = "true" ]; then
- if [ ${NEED_DEX} = "true" -a ${SKIP_DX_MERGER} = "false" ]; then
- ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex \
- --dump-width=1000 ${DX_FLAGS} classes
- fi
- fi
-fi
-
-if [ "${HAS_SMALI}" = "true" ]; then
- # Compile Smali classes
- ${SMALI} -JXmx512m assemble ${SMALI_ARGS} --output smali_classes.dex `find smali -name '*.smali'`
-
- # Don't bother with dexmerger if we provide our own main function in a smali file.
- if [ ${SKIP_DX_MERGER} = "false" ]; then
- ${DXMERGER} classes.dex classes.dex smali_classes.dex
- else
- mv smali_classes.dex classes.dex
- fi
-fi
-
-if [ ${HAS_SRC_EX} = "true" ]; then
- if [ ${USE_JACK} = "true" ]; then
- # Rename previous "classes.dex" so it is not overwritten.
- mv classes.dex classes-1.dex
- #TODO find another way to append src.jack to the jack classpath
- ${JACK}:src.jack ${JACK_ARGS} --output-dex . src-ex
- zip $TEST_NAME-ex.jar classes.dex
- # Restore previous "classes.dex" so it can be zipped.
- mv classes-1.dex classes.dex
- else
- mkdir classes-ex
- ${JAVAC} ${JAVAC_ARGS} -d classes-ex -cp classes `find src-ex -name '*.java'`
- if [ ${NEED_DEX} = "true" ]; then
- ${DX} -JXmx256m --debug --dex --dump-to=classes-ex.lst --output=classes-ex.dex \
- --dump-width=1000 ${DX_FLAGS} classes-ex
-
- # quick shuffle so that the stored name is "classes.dex"
- mv classes.dex classes-1.dex
- mv classes-ex.dex classes.dex
- zip $TEST_NAME-ex.jar classes.dex
- mv classes.dex classes-ex.dex
- mv classes-1.dex classes.dex
- fi
- fi
-fi
-
-# Create a single jar with two dex files for multidex.
-if [ ${HAS_SRC_MULTIDEX} = "true" ]; then
- zip $TEST_NAME.jar classes.dex classes2.dex
-elif [ ${NEED_DEX} = "true" ]; then
- zip $TEST_NAME.jar classes.dex
-fi
diff --git a/test/636-arm64-veneer-pool/build b/test/636-arm64-veneer-pool/build
index 27cc4d6..eba22fc 100755
--- a/test/636-arm64-veneer-pool/build
+++ b/test/636-arm64-veneer-pool/build
@@ -19,4 +19,9 @@
# Use javac+dx instead of jack.
export USE_JACK=false
-./default-build "$@"
+
+# Don't use desugar because the bootclasspath jars will be missing
+# on a platform build compiled with ANDROID_COMPILE_WITH_JACK=true.
+export USE_DESUGAR=false
+
+./default-build
diff --git a/test/641-checker-arraycopy/build b/test/641-checker-arraycopy/build
index 9abc618..12e4423 100644
--- a/test/641-checker-arraycopy/build
+++ b/test/641-checker-arraycopy/build
@@ -21,4 +21,8 @@
# the typed System.arraycopy versions directly.
export USE_JACK=false
-./default-build
+# Don't use desugar because the bootclasspath jars will be missing
+# on a platform build compiled with ANDROID_COMPILE_WITH_JACK=true.
+export USE_DESUGAR=false
+
+./default-build "$@"
diff --git a/test/etc/default-build b/test/etc/default-build
index 0508b85..9e2a6e2 100755
--- a/test/etc/default-build
+++ b/test/etc/default-build
@@ -70,6 +70,9 @@
SKIP_DX_MERGER="false"
EXPERIMENTAL=""
+BUILD_MODE="target"
+DEV_MODE="no"
+
# The key for default arguments if no experimental things are enabled.
DEFAULT_EXPERIMENT="no-experiment"
@@ -137,6 +140,15 @@
WITH_ZIP_ALIGN=true
ZIP_ALIGN_BYTES="$1"
shift
+ elif [ "x$1" = "x--host" ]; then
+ BUILD_MODE="host"
+ shift
+ elif [ "x$1" = "x--target" ]; then
+ BUILD_MODE="target"
+ shift
+ elif [ "x$1" = "x--dev" ]; then
+ DEV_MODE="yes"
+ shift
elif expr "x$1" : "x--" >/dev/null 2>&1; then
echo "unknown $0 option: $1" 1>&2
exit 1
@@ -185,6 +197,41 @@
fi
}
+function desugar() {
+ local desugar_args=--mode=host
+ if [[ $BUILD_MODE == target ]]; then
+ desugar_args=--mode=target
+ fi
+
+ if [[ $DEV_MODE == yes ]]; then
+ desugar_args="$desugar_args --show-commands"
+ fi
+
+ "${ANDROID_BUILD_TOP}/art/tools/desugar.sh" --core-only $desugar_args "$@"
+}
+
+# Make a "dex" file given a directory of classes in $1.
+# Also calls desugar on the classes first to convert lambdas.
+function make_dex() {
+ local name="$1"
+
+ local dx_input
+ if [[ "$USE_DESUGAR" == "true" ]]; then
+ # Make a jar first so desugar doesn't need every .class file individually.
+ jar cf "$name.before-desugar.jar" -C "$name" .
+
+ dx_input="${name}.desugar.jar"
+
+ # Make desugared JAR.
+ desugar --input "$name.before-desugar.jar" --output "$dx_input"
+ else
+ dx_input="${name}"
+ fi
+
+ # Make dex file from desugared JAR.
+ ${DX} -JXmx256m --debug --dex --dump-to=${name}.lst --output=${name}.dex --dump-width=1000 ${DX_FLAGS} "${dx_input}"
+}
+
if [ -e classes.dex ]; then
zip $TEST_NAME.jar classes.dex
exit 0
@@ -209,9 +256,9 @@
${JACK} --import classes.jill.jar --output-dex .
else
if [ ${NEED_DEX} = "true" ]; then
- ${DX} -JXmx256m --debug --dex --dump-to=classes-ex.lst --output=classes.dex --dump-width=1000 ${DX_FLAGS} classes-ex
+ make_dex classes-ex
zip ${TEST_NAME}-ex.jar classes.dex
- ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex --dump-width=1000 ${DX_FLAGS} classes
+ make_dex classes
fi
fi
else
@@ -254,8 +301,7 @@
mkdir classes2
${JAVAC} -implicit:none -classpath src -d classes2 `find src-multidex -name '*.java'`
if [ ${NEED_DEX} = "true" ]; then
- ${DX} -JXmx256m --debug --dex --dump-to=classes2.lst --output=classes2.dex \
- --dump-width=1000 ${DX_FLAGS} classes2
+ make_dex classes2
fi
fi
@@ -266,8 +312,7 @@
if [ "${HAS_SRC}" = "true" ] || [ "${HAS_SRC2}" = "true" ]; then
if [ ${NEED_DEX} = "true" -a ${SKIP_DX_MERGER} = "false" ]; then
- ${DX} -JXmx256m --debug --dex --dump-to=classes.lst --output=classes.dex \
- --dump-width=1000 ${DX_FLAGS} classes
+ make_dex classes
fi
fi
fi
@@ -311,8 +356,7 @@
mkdir classes-ex
${JAVAC} ${JAVAC_ARGS} -d classes-ex -cp classes `find src-ex -name '*.java'`
if [ ${NEED_DEX} = "true" ]; then
- ${DX} -JXmx256m --debug --dex --dump-to=classes-ex.lst --output=classes-ex.dex \
- --dump-width=1000 ${DX_FLAGS} classes-ex
+ make_dex classes-ex
# quick shuffle so that the stored name is "classes.dex"
mv classes.dex classes-1.dex
diff --git a/test/knownfailures.json b/test/knownfailures.json
index 8843dc8..9a8f3be 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -601,38 +601,28 @@
"004-ReferenceMap",
"004-StackWalk",
"048-reflect-v8",
+ "065-mismatched-implements",
"089-many-methods",
"138-duplicate-classes-check",
"146-bad-interface",
"157-void-class",
+ "529-checker-unresolved",
"563-checker-invoke-super",
"580-checker-string-fact-intrinsics",
"596-monitor-inflation",
"604-hot-static-interface",
+ "608-checker-unresolved-lse",
"612-jit-dex-cache",
"613-inlining-dex-cache",
"616-cha-interface-default",
"636-wrong-static-access",
+ "648-inline-caches-unresolved",
"909-attach-agent",
"910-methods",
"911-get-stack-trace",
"912-classes",
"913-heaps",
- "914-hello-obsolescence",
- "915-obsolete-2",
- "916-obsolete-jit",
- "919-obsolete-fields",
- "921-hello-failure",
- "926-multi-obsolescence",
- "940-recursive-obsolete",
- "941-recurive-obsolete-jit",
- "942-private-recursive",
- "943-private-recursive-jit",
- "945-obsolete-native",
- "946-obsolete-throw",
"948-change-annotations",
- "950-redefine-intrinsic",
- "951-threaded-obsolete",
"952-invoke-custom",
"953-invoke-polymorphic-compiler",
"956-methodhandles",
@@ -648,9 +638,7 @@
"966-default-conflict",
"967-default-ame",
"969-iface-super",
- "981-dedup-original-dex",
- "984-obsolete-invoke",
- "985-re-obsolete"
+ "981-dedup-original-dex"
],
"description": "The tests above fail with --build-with-javac-dx.",
"env_vars": {"ANDROID_COMPILE_WITH_JACK": "false"},
diff --git a/test/run-test b/test/run-test
index 41a0dc2..ba1f992 100755
--- a/test/run-test
+++ b/test/run-test
@@ -46,6 +46,7 @@
export DEX_LOCATION=/data/run-test/${test_dir}
export NEED_DEX="true"
export USE_JACK="true"
+export USE_DESUGAR="true"
export SMALI_ARGS=""
# If dx was not set by the environment variable, assume it is in the path.
@@ -771,6 +772,16 @@
err_echo "ulimit file size setting failed"
fi
+if [[ "$target_mode" == "yes" ]]; then
+ build_args="$build_args --target"
+else
+ build_args="$build_args --host"
+fi
+
+if [[ "$dev_mode" == "yes" ]]; then
+ build_args="$build_args --dev"
+fi
+
good="no"
good_build="yes"
good_run="yes"
diff --git a/test/ti-stress/stress.cc b/test/ti-stress/stress.cc
index 497db1c..515a391 100644
--- a/test/ti-stress/stress.cc
+++ b/test/ti-stress/stress.cc
@@ -18,6 +18,7 @@
#include <stdio.h>
#include <iostream>
#include <fstream>
+#include <memory>
#include <stdio.h>
#include <sstream>
#include <strstream>
@@ -87,6 +88,142 @@
return ReadIntoBuffer(data->out_temp_dex, dex);
}
+class ScopedThreadInfo {
+ public:
+ ScopedThreadInfo(jvmtiEnv* jvmtienv, JNIEnv* env, jthread thread)
+ : jvmtienv_(jvmtienv), env_(env), free_name_(false) {
+ memset(&info_, 0, sizeof(info_));
+ if (thread == nullptr) {
+ info_.name = const_cast<char*>("<NULLPTR>");
+ } else if (jvmtienv->GetThreadInfo(thread, &info_) != JVMTI_ERROR_NONE) {
+ info_.name = const_cast<char*>("<UNKNOWN THREAD>");
+ } else {
+ free_name_ = true;
+ }
+ }
+
+ ~ScopedThreadInfo() {
+ if (free_name_) {
+ jvmtienv_->Deallocate(reinterpret_cast<unsigned char*>(info_.name));
+ }
+ env_->DeleteLocalRef(info_.thread_group);
+ env_->DeleteLocalRef(info_.context_class_loader);
+ }
+
+ const char* GetName() const {
+ return info_.name;
+ }
+
+ private:
+ jvmtiEnv* jvmtienv_;
+ JNIEnv* env_;
+ bool free_name_;
+ jvmtiThreadInfo info_;
+};
+
+class ScopedClassInfo {
+ public:
+ ScopedClassInfo(jvmtiEnv* jvmtienv, jclass c)
+ : jvmtienv_(jvmtienv),
+ class_(c),
+ name_(nullptr),
+ generic_(nullptr) {}
+
+ ~ScopedClassInfo() {
+ jvmtienv_->Deallocate(reinterpret_cast<unsigned char*>(name_));
+ jvmtienv_->Deallocate(reinterpret_cast<unsigned char*>(generic_));
+ }
+
+ bool Init() {
+ return jvmtienv_->GetClassSignature(class_, &name_, &generic_) == JVMTI_ERROR_NONE;
+ }
+
+ jclass GetClass() const {
+ return class_;
+ }
+ const char* GetName() const {
+ return name_;
+ }
+ const char* GetGeneric() const {
+ return generic_;
+ }
+
+ private:
+ jvmtiEnv* jvmtienv_;
+ jclass class_;
+ char* name_;
+ char* generic_;
+};
+
+class ScopedMethodInfo {
+ public:
+ ScopedMethodInfo(jvmtiEnv* jvmtienv, JNIEnv* env, jmethodID m)
+ : jvmtienv_(jvmtienv),
+ env_(env),
+ method_(m),
+ declaring_class_(nullptr),
+ class_info_(nullptr),
+ name_(nullptr),
+ signature_(nullptr),
+ generic_(nullptr) {}
+
+ ~ScopedMethodInfo() {
+ env_->DeleteLocalRef(declaring_class_);
+ jvmtienv_->Deallocate(reinterpret_cast<unsigned char*>(name_));
+ jvmtienv_->Deallocate(reinterpret_cast<unsigned char*>(signature_));
+ jvmtienv_->Deallocate(reinterpret_cast<unsigned char*>(generic_));
+ }
+
+ bool Init() {
+ if (jvmtienv_->GetMethodDeclaringClass(method_, &declaring_class_) != JVMTI_ERROR_NONE) {
+ return false;
+ }
+ class_info_.reset(new ScopedClassInfo(jvmtienv_, declaring_class_));
+ return class_info_->Init() &&
+ (jvmtienv_->GetMethodName(method_, &name_, &signature_, &generic_) == JVMTI_ERROR_NONE);
+ }
+
+ const ScopedClassInfo& GetDeclaringClassInfo() const {
+ return *class_info_;
+ }
+
+ jclass GetDeclaringClass() const {
+ return declaring_class_;
+ }
+
+ const char* GetName() const {
+ return name_;
+ }
+
+ const char* GetSignature() const {
+ return signature_;
+ }
+
+ const char* GetGeneric() const {
+ return generic_;
+ }
+
+ private:
+ jvmtiEnv* jvmtienv_;
+ JNIEnv* env_;
+ jmethodID method_;
+ jclass declaring_class_;
+ std::unique_ptr<ScopedClassInfo> class_info_;
+ char* name_;
+ char* signature_;
+ char* generic_;
+
+ friend std::ostream& operator<<(std::ostream &os, ScopedMethodInfo const& m);
+};
+
+std::ostream& operator<<(std::ostream &os, const ScopedMethodInfo* m) {
+ return os << *m;
+}
+
+std::ostream& operator<<(std::ostream &os, ScopedMethodInfo const& m) {
+ return os << m.GetDeclaringClassInfo().GetName() << "->" << m.GetName() << m.GetSignature();
+}
+
static void doJvmtiMethodBind(jvmtiEnv* jvmtienv,
JNIEnv* env,
jthread thread,
@@ -94,38 +231,14 @@
void* address,
/*out*/void** out_address) {
*out_address = address;
- jvmtiThreadInfo info;
- if (thread == nullptr) {
- info.name = const_cast<char*>("<NULLPTR>");
- } else if (jvmtienv->GetThreadInfo(thread, &info) != JVMTI_ERROR_NONE) {
- info.name = const_cast<char*>("<UNKNOWN THREAD>");
- }
- char *fname, *fsig, *fgen;
- char *cname, *cgen;
- jclass klass = nullptr;
- if (jvmtienv->GetMethodDeclaringClass(m, &klass) != JVMTI_ERROR_NONE) {
- LOG(ERROR) << "Unable to get method declaring class!";
+ ScopedThreadInfo thread_info(jvmtienv, env, thread);
+ ScopedMethodInfo method_info(jvmtienv, env, m);
+ if (!method_info.Init()) {
+ LOG(ERROR) << "Unable to get method info!";
return;
}
- if (jvmtienv->GetMethodName(m, &fname, &fsig, &fgen) != JVMTI_ERROR_NONE) {
- LOG(ERROR) << "Unable to get method name!";
- env->DeleteLocalRef(klass);
- return;
- }
- if (jvmtienv->GetClassSignature(klass, &cname, &cgen) != JVMTI_ERROR_NONE) {
- LOG(ERROR) << "Unable to get class name!";
- env->DeleteLocalRef(klass);
- return;
- }
- LOG(INFO) << "Loading native method \"" << cname << "->" << fname << fsig << "\". Thread is \""
- << info.name << "\"";
- jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(cname));
- jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(cgen));
- jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(fname));
- jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(fsig));
- jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(fgen));
- env->DeleteLocalRef(klass);
- return;
+ LOG(INFO) << "Loading native method \"" << method_info << "\". Thread is "
+ << thread_info.GetName();
}
static std::string GetName(jvmtiEnv* jvmtienv, JNIEnv* jnienv, jobject obj) {
@@ -197,80 +310,32 @@
jmethodID m,
jboolean was_popped_by_exception,
jvalue val) {
- jvmtiThreadInfo info;
- if (thread == nullptr) {
- info.name = const_cast<char*>("<NULLPTR>");
- } else if (jvmtienv->GetThreadInfo(thread, &info) != JVMTI_ERROR_NONE) {
- // LOG(WARNING) << "Unable to get thread info!";
- info.name = const_cast<char*>("<UNKNOWN THREAD>");
- }
- char *fname, *fsig, *fgen;
- char *cname, *cgen;
- jclass klass = nullptr;
- if (jvmtienv->GetMethodDeclaringClass(m, &klass) != JVMTI_ERROR_NONE) {
- LOG(ERROR) << "Unable to get method declaring class!";
+ ScopedThreadInfo info(jvmtienv, env, thread);
+ ScopedMethodInfo method_info(jvmtienv, env, m);
+ if (!method_info.Init()) {
+ LOG(ERROR) << "Unable to get method info!";
return;
}
- if (jvmtienv->GetMethodName(m, &fname, &fsig, &fgen) != JVMTI_ERROR_NONE) {
- LOG(ERROR) << "Unable to get method name!";
- env->DeleteLocalRef(klass);
- return;
- }
- if (jvmtienv->GetClassSignature(klass, &cname, &cgen) != JVMTI_ERROR_NONE) {
- LOG(ERROR) << "Unable to get class name!";
- env->DeleteLocalRef(klass);
- return;
- }
- std::string type(fsig);
+ std::string type(method_info.GetSignature());
type = type.substr(type.find(")") + 1);
std::string out_val(was_popped_by_exception ? "" : GetValOf(jvmtienv, env, type, val));
- LOG(INFO) << "Leaving method \"" << cname << "->" << fname << fsig << "\". Thread is \""
- << info.name << "\"." << std::endl
+ LOG(INFO) << "Leaving method \"" << method_info << "\". Thread is \"" << info.GetName() << "\"."
+ << std::endl
<< " Cause: " << (was_popped_by_exception ? "exception" : "return ")
<< out_val << ".";
- jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(cname));
- jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(cgen));
- jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(fname));
- jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(fsig));
- jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(fgen));
- env->DeleteLocalRef(klass);
}
void JNICALL MethodEntryHook(jvmtiEnv* jvmtienv,
JNIEnv* env,
jthread thread,
jmethodID m) {
- jvmtiThreadInfo info;
- if (thread == nullptr) {
- info.name = const_cast<char*>("<NULLPTR>");
- } else if (jvmtienv->GetThreadInfo(thread, &info) != JVMTI_ERROR_NONE) {
- info.name = const_cast<char*>("<UNKNOWN THREAD>");
- }
- char *fname, *fsig, *fgen;
- char *cname, *cgen;
- jclass klass = nullptr;
- if (jvmtienv->GetMethodDeclaringClass(m, &klass) != JVMTI_ERROR_NONE) {
- LOG(ERROR) << "Unable to get method declaring class!";
+ ScopedThreadInfo info(jvmtienv, env, thread);
+ ScopedMethodInfo method_info(jvmtienv, env, m);
+ if (!method_info.Init()) {
+ LOG(ERROR) << "Unable to get method info!";
return;
}
- if (jvmtienv->GetMethodName(m, &fname, &fsig, &fgen) != JVMTI_ERROR_NONE) {
- LOG(ERROR) << "Unable to get method name!";
- env->DeleteLocalRef(klass);
- return;
- }
- if (jvmtienv->GetClassSignature(klass, &cname, &cgen) != JVMTI_ERROR_NONE) {
- LOG(ERROR) << "Unable to get class name!";
- env->DeleteLocalRef(klass);
- return;
- }
- LOG(INFO) << "Entering method \"" << cname << "->" << fname << fsig << "\". Thread is \""
- << info.name << "\"";
- jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(cname));
- jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(cgen));
- jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(fname));
- jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(fsig));
- jvmtienv->Deallocate(reinterpret_cast<unsigned char*>(fgen));
- env->DeleteLocalRef(klass);
+ LOG(INFO) << "Entering method \"" << method_info << "\". Thread is \"" << info.GetName() << "\"";
}
// The hook we are using.
diff --git a/tools/bootjars.sh b/tools/bootjars.sh
new file mode 100755
index 0000000..bb47e55
--- /dev/null
+++ b/tools/bootjars.sh
@@ -0,0 +1,87 @@
+#!/bin/bash
+#
+# Copyright (C) 2017 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.
+
+#
+# This script lists the boot jars that an ART bootclasspath would need.
+#
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+TOP="$DIR/../.."
+
+source "${TOP}/build/envsetup.sh" >&/dev/null # import get_build_var
+
+selected_env_var=
+core_jars_only=n
+print_file_path=n
+mode=target
+while true; do
+ case $1 in
+ --help)
+ echo "Usage: $0 [--core] [--path] [--host|--target] [--help]"
+ exit 0
+ ;;
+ --core)
+ core_jars_only=y
+ ;;
+ --path)
+ print_file_path=y
+ ;;
+ --host)
+ mode=host
+ ;;
+ --target)
+ mode=target
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+
+if [[ $mode == target ]]; then
+ if [[ $core_jars_only == y ]]; then
+ selected_env_var=TARGET_CORE_JARS
+ else
+ selected_env_var=PRODUCT_BOOT_JARS
+ fi
+ intermediates_env_var=TARGET_OUT_COMMON_INTERMEDIATES
+elif [[ $mode == host ]]; then
+ if [[ $core_jars_only == n ]]; then
+ echo "Error: --host does not have non-core boot jars, --core required" >&2
+ exit 1
+ fi
+ selected_env_var=HOST_CORE_JARS
+ intermediates_env_var=HOST_OUT_COMMON_INTERMEDIATES
+fi
+
+boot_jars_list=$(get_build_var "$selected_env_var")
+
+# Print only the list of boot jars.
+if [[ $print_file_path == n ]]; then
+ echo $boot_jars_list
+ exit 0
+fi
+
+# Print the file path (relative to $TOP) to the classes.jar of each boot jar in the intermediates directory.
+intermediates_dir=$(get_build_var "$intermediates_env_var")
+
+# turn the file path into an absolute path
+intermediates_dir=$(readlink -f $TOP/$intermediates_dir)
+
+for jar in $boot_jars_list; do
+ echo "$intermediates_dir/JAVA_LIBRARIES/${jar}_intermediates/classes.jar"
+done
diff --git a/tools/desugar.sh b/tools/desugar.sh
new file mode 100755
index 0000000..43541aa
--- /dev/null
+++ b/tools/desugar.sh
@@ -0,0 +1,91 @@
+#!/bin/bash
+#
+# Copyright (C) 2017 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.
+
+#
+# Calls desugar.jar with the --bootclasspath_entry values passed in automatically.
+# (This avoids having to manually set a boot class path).
+#
+#
+# Script-specific args:
+# --mode=[host|target]: Select between host or target bootclasspath (default target).
+# --core-only: Use only "core" bootclasspath (e.g. do not include framework).
+# --show-commands: Print the desugar command being executed.
+# --help: Print above list of args.
+#
+# All other args are forwarded to desugar.jar
+#
+
+DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+TOP=$DIR/../..
+
+pushd "$TOP" >/dev/null # back to android root.
+
+out=${OUT_DIR:-out}
+desugar_jar=$out/host/linux-x86/framework/desugar.jar
+
+if ! [[ -f $desugar_jar ]]; then
+ echo "Error: Missing $desugar_jar; did you do a build?" >&2
+ exit 1
+fi
+
+desugar_jar=$(readlink -f "$desugar_jar") # absolute path to desugar jar
+popd >/dev/null
+
+bootjars_args=
+mode=target
+showcommands=n
+while true; do
+ case $1 in
+ --help)
+ echo "Usage: $0 [--mode=host|target] [--core-only] [--show-commands] <desugar args>"
+ exit 0
+ ;;
+ --mode=host)
+ bootjars_args="$bootjars_args --host"
+ ;;
+ --mode=target)
+ bootjars_args="$bootjars_args --target"
+ ;;
+ --core-only)
+ bootjars_args="$bootjars_args --core"
+ ;;
+ --show-commands)
+ showcommands=y
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+
+desugar_args=()
+boot_class_path_list=$($TOP/art/tools/bootjars.sh $bootjars_args --path)
+
+for path in $boot_class_path_list; do
+ desugar_args+=(--bootclasspath_entry="$path")
+done
+
+if [[ ${#desugar_args[@]} -eq 0 ]]; then
+ echo "FATAL: Missing bootjars.sh file path list" >&2
+ exit 1
+fi
+
+if [[ $showcommands == y ]]; then
+ echo java -jar "$desugar_jar" "${desugar_args[@]}" "$@"
+fi
+
+java -jar "$desugar_jar" "${desugar_args[@]}" "$@"