Merge "ART: Fix Segment Fault with null owner while monitor logging is enabled"
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index 406c2a1..b157d8e 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -79,6 +79,7 @@
compiler/optimizing/codegen_test.cc \
compiler/optimizing/dominator_test.cc \
compiler/optimizing/find_loops_test.cc \
+ compiler/optimizing/linearize_test.cc \
compiler/optimizing/liveness_test.cc \
compiler/optimizing/pretty_printer_test.cc \
compiler/optimizing/ssa_test.cc \
diff --git a/build/Android.libcxx.mk b/build/Android.libcxx.mk
index 3dd1eb7..f84e957 100644
--- a/build/Android.libcxx.mk
+++ b/build/Android.libcxx.mk
@@ -14,7 +14,10 @@
# limitations under the License.
#
+LOCAL_ADDITIONAL_DEPENDENCIES += art/build/Android.libcxx.mk
+
ifneq ($(LOCAL_IS_HOST_MODULE),true)
include external/stlport/libstlport.mk
+ LOCAL_CFLAGS += -DART_WITH_STLPORT=1
# include external/libcxx/libcxx.mk
endif
diff --git a/compiler/compiled_method.h b/compiler/compiled_method.h
index 844b53c..c3c9961 100644
--- a/compiler/compiled_method.h
+++ b/compiler/compiled_method.h
@@ -22,7 +22,7 @@
#include "instruction_set.h"
#include "utils.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace llvm {
class Function;
diff --git a/compiler/dex/frontend.cc b/compiler/dex/frontend.cc
index 144594e..3bc060b 100644
--- a/compiler/dex/frontend.cc
+++ b/compiler/dex/frontend.cc
@@ -147,8 +147,8 @@
// Instruction::MOVE_RESULT,
// Instruction::MOVE_RESULT_WIDE,
// Instruction::MOVE_RESULT_OBJECT,
- // Instruction::MOVE_EXCEPTION,
- // Instruction::RETURN_VOID,
+ Instruction::MOVE_EXCEPTION,
+ Instruction::RETURN_VOID,
// Instruction::RETURN,
// Instruction::RETURN_WIDE,
// Instruction::RETURN_OBJECT,
@@ -163,8 +163,8 @@
// Instruction::CONST_STRING,
// Instruction::CONST_STRING_JUMBO,
// Instruction::CONST_CLASS,
- // Instruction::MONITOR_ENTER,
- // Instruction::MONITOR_EXIT,
+ Instruction::MONITOR_ENTER,
+ Instruction::MONITOR_EXIT,
// Instruction::CHECK_CAST,
// Instruction::INSTANCE_OF,
// Instruction::ARRAY_LENGTH,
@@ -173,7 +173,7 @@
// Instruction::FILLED_NEW_ARRAY,
// Instruction::FILLED_NEW_ARRAY_RANGE,
// Instruction::FILL_ARRAY_DATA,
- // Instruction::THROW,
+ Instruction::THROW,
// Instruction::GOTO,
// Instruction::GOTO_16,
// Instruction::GOTO_32,
@@ -230,14 +230,14 @@
// Instruction::IPUT_BYTE,
// Instruction::IPUT_CHAR,
// Instruction::IPUT_SHORT,
- // Instruction::SGET,
+ Instruction::SGET,
// Instruction::SGET_WIDE,
- // Instruction::SGET_OBJECT,
+ Instruction::SGET_OBJECT,
// Instruction::SGET_BOOLEAN,
// Instruction::SGET_BYTE,
// Instruction::SGET_CHAR,
// Instruction::SGET_SHORT,
- // Instruction::SPUT,
+ Instruction::SPUT,
// Instruction::SPUT_WIDE,
// Instruction::SPUT_OBJECT,
// Instruction::SPUT_BOOLEAN,
@@ -350,7 +350,7 @@
// Instruction::AND_INT_LIT16,
// Instruction::OR_INT_LIT16,
// Instruction::XOR_INT_LIT16,
- // Instruction::ADD_INT_LIT8,
+ Instruction::ADD_INT_LIT8,
// Instruction::RSUB_INT_LIT8,
// Instruction::MUL_INT_LIT8,
// Instruction::DIV_INT_LIT8,
@@ -403,7 +403,7 @@
// kMirOpNullCheck,
// kMirOpRangeCheck,
// kMirOpDivZeroCheck,
- // kMirOpCheck,
+ kMirOpCheck,
// kMirOpCheckPart2,
// kMirOpSelect,
// kMirOpLast,
diff --git a/compiler/dex/local_value_numbering.h b/compiler/dex/local_value_numbering.h
index 6d67afb..7049f8c 100644
--- a/compiler/dex/local_value_numbering.h
+++ b/compiler/dex/local_value_numbering.h
@@ -18,7 +18,7 @@
#define ART_COMPILER_DEX_LOCAL_VALUE_NUMBERING_H_
#include "compiler_internals.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "utils/scoped_arena_allocator.h"
#include "utils/scoped_arena_containers.h"
diff --git a/compiler/dex/mir_analysis.cc b/compiler/dex/mir_analysis.cc
index c3b5a25..1c9e2e2 100644
--- a/compiler/dex/mir_analysis.cc
+++ b/compiler/dex/mir_analysis.cc
@@ -23,7 +23,7 @@
#include "dex/quick/dex_file_method_inliner.h"
#include "dex/quick/dex_file_to_method_inliner_map.h"
#include "driver/compiler_options.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "utils/scoped_arena_containers.h"
namespace art {
diff --git a/compiler/dex/quick/arm64/arm64_lir.h b/compiler/dex/quick/arm64/arm64_lir.h
index 7ae4b02..f98e366 100644
--- a/compiler/dex/quick/arm64/arm64_lir.h
+++ b/compiler/dex/quick/arm64/arm64_lir.h
@@ -151,6 +151,9 @@
rxzr = rx31,
rwsp = rw31,
rsp = rx31,
+ // TODO: rx4 is an argument register in C ABI which is not a good idea,
+ // But we need to decide to use caller save register in C ABI or callee save register.
+ // Because it will result to different implementation in the trampoline.
rA64_SUSPEND = rx4,
rA64_SELF = rx18,
rA64_SP = rx31,
diff --git a/compiler/dex/quick/arm64/assemble_arm64.cc b/compiler/dex/quick/arm64/assemble_arm64.cc
index 8accd0a..93caf89 100644
--- a/compiler/dex/quick/arm64/assemble_arm64.cc
+++ b/compiler/dex/quick/arm64/assemble_arm64.cc
@@ -176,7 +176,7 @@
kFmtRegROrSp, 9, 5, kFmtBitBlt, 21, 10, kFmtBitBlt, 23, 22,
kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_USE0 | SETS_CCODES,
"cmn", "!0R, #!1d!2T", kFixupNone),
- ENCODING_MAP(WIDE(kA64Cmp3Rro), SF_VARIANTS(0x6b20001f),
+ ENCODING_MAP(WIDE(kA64Cmp3Rro), SF_VARIANTS(0x6b00001f),
kFmtRegROrSp, 9, 5, kFmtRegR, 20, 16, kFmtShift, -1, -1,
kFmtUnused, -1, -1, IS_TERTIARY_OP | REG_USE01 | SETS_CCODES,
"cmp", "!0R, !1r!2o", kFixupNone),
@@ -637,7 +637,7 @@
}
// Now check that the requirements are satisfied.
- RegStorage reg(operand);
+ RegStorage reg(operand | RegStorage::kValid);
const char *expected = nullptr;
if (want_float) {
if (!reg.IsFloat()) {
diff --git a/compiler/dex/quick/arm64/call_arm64.cc b/compiler/dex/quick/arm64/call_arm64.cc
index 1bcf19b..136a04f 100644
--- a/compiler/dex/quick/arm64/call_arm64.cc
+++ b/compiler/dex/quick/arm64/call_arm64.cc
@@ -194,137 +194,101 @@
* details see monitor.cc.
*/
void Arm64Mir2Lir::GenMonitorEnter(int opt_flags, RegLocation rl_src) {
+ // x0/w0 = object
+ // w1 = thin lock thread id
+ // x2 = address of lock word
+ // w3 = lock word / store failure
+ // TUNING: How much performance we get when we inline this?
+ // Since we've already flush all register.
FlushAllRegs();
- // FIXME: need separate LoadValues for object references.
- LoadValueDirectFixed(rl_src, rs_x0); // Get obj
+ LoadValueDirectFixed(rl_src, rs_w0);
LockCallTemps(); // Prepare for explicit register usage
- constexpr bool kArchVariantHasGoodBranchPredictor = false; // TODO: true if cortex-A15.
- if (kArchVariantHasGoodBranchPredictor) {
- LIR* null_check_branch = nullptr;
- if ((opt_flags & MIR_IGNORE_NULL_CHECK) && !(cu_->disable_opt & (1 << kNullCheckElimination))) {
- null_check_branch = nullptr; // No null check.
- } else {
- // If the null-check fails its handled by the slow-path to reduce exception related meta-data.
- if (Runtime::Current()->ExplicitNullChecks()) {
- null_check_branch = OpCmpImmBranch(kCondEq, rs_x0, 0, NULL);
- }
- }
- Load32Disp(rs_rA64_SELF, Thread::ThinLockIdOffset<8>().Int32Value(), rs_x2);
- NewLIR3(kA64Ldxr2rX, rx1, rx0, mirror::Object::MonitorOffset().Int32Value() >> 2);
- MarkPossibleNullPointerException(opt_flags);
- LIR* not_unlocked_branch = OpCmpImmBranch(kCondNe, rs_x1, 0, NULL);
- NewLIR4(kA64Stxr3wrX, rx1, rx2, rx0, mirror::Object::MonitorOffset().Int32Value() >> 2);
- LIR* lock_success_branch = OpCmpImmBranch(kCondEq, rs_x1, 0, NULL);
-
-
- LIR* slow_path_target = NewLIR0(kPseudoTargetLabel);
- not_unlocked_branch->target = slow_path_target;
- if (null_check_branch != nullptr) {
- null_check_branch->target = slow_path_target;
- }
- // TODO: move to a slow path.
- // Go expensive route - artLockObjectFromCode(obj);
- LoadWordDisp(rs_rA64_SELF, QUICK_ENTRYPOINT_OFFSET(8, pLockObject).Int32Value(), rs_rA64_LR);
- ClobberCallerSave();
- LIR* call_inst = OpReg(kOpBlx, rs_rA64_LR);
- MarkSafepointPC(call_inst);
-
- LIR* success_target = NewLIR0(kPseudoTargetLabel);
- lock_success_branch->target = success_target;
- GenMemBarrier(kLoadLoad);
+ LIR* null_check_branch = nullptr;
+ if ((opt_flags & MIR_IGNORE_NULL_CHECK) && !(cu_->disable_opt & (1 << kNullCheckElimination))) {
+ null_check_branch = nullptr; // No null check.
} else {
- // Explicit null-check as slow-path is entered using an IT.
- GenNullCheck(rs_x0, opt_flags);
- Load32Disp(rs_rA64_SELF, Thread::ThinLockIdOffset<8>().Int32Value(), rs_x2);
- MarkPossibleNullPointerException(opt_flags);
- NewLIR3(kA64Ldxr2rX, rx1, rx0, mirror::Object::MonitorOffset().Int32Value() >> 2);
- OpRegImm(kOpCmp, rs_x1, 0);
- OpIT(kCondEq, "");
- NewLIR4(kA64Stxr3wrX/*eq*/, rx1, rx2, rx0, mirror::Object::MonitorOffset().Int32Value() >> 2);
- OpRegImm(kOpCmp, rs_x1, 0);
- OpIT(kCondNe, "T");
- // Go expensive route - artLockObjectFromCode(self, obj);
- LoadWordDisp/*ne*/(rs_rA64_SELF, QUICK_ENTRYPOINT_OFFSET(8, pLockObject).Int32Value(),
- rs_rA64_LR);
- ClobberCallerSave();
- LIR* call_inst = OpReg(kOpBlx/*ne*/, rs_rA64_LR);
- MarkSafepointPC(call_inst);
- GenMemBarrier(kLoadLoad);
+ // If the null-check fails its handled by the slow-path to reduce exception related meta-data.
+ if (Runtime::Current()->ExplicitNullChecks()) {
+ null_check_branch = OpCmpImmBranch(kCondEq, rs_x0, 0, NULL);
+ }
}
+ Load32Disp(rs_rA64_SELF, Thread::ThinLockIdOffset<8>().Int32Value(), rs_w1);
+ OpRegRegImm(kOpAdd, rs_x2, rs_x0, mirror::Object::MonitorOffset().Int32Value());
+ NewLIR2(kA64Ldxr2rX, rw3, rx2);
+ MarkPossibleNullPointerException(opt_flags);
+ LIR* not_unlocked_branch = OpCmpImmBranch(kCondNe, rs_x1, 0, NULL);
+ NewLIR3(kA64Stxr3wrX, rw3, rw1, rx2);
+ LIR* lock_success_branch = OpCmpImmBranch(kCondEq, rs_x1, 0, NULL);
+
+ LIR* slow_path_target = NewLIR0(kPseudoTargetLabel);
+ not_unlocked_branch->target = slow_path_target;
+ if (null_check_branch != nullptr) {
+ null_check_branch->target = slow_path_target;
+ }
+ // TODO: move to a slow path.
+ // Go expensive route - artLockObjectFromCode(obj);
+ LoadWordDisp(rs_rA64_SELF, QUICK_ENTRYPOINT_OFFSET(8, pLockObject).Int32Value(), rs_rA64_LR);
+ ClobberCallerSave();
+ LIR* call_inst = OpReg(kOpBlx, rs_rA64_LR);
+ MarkSafepointPC(call_inst);
+
+ LIR* success_target = NewLIR0(kPseudoTargetLabel);
+ lock_success_branch->target = success_target;
+ GenMemBarrier(kLoadLoad);
}
/*
* Handle thin locked -> unlocked transition inline or else call out to quick entrypoint. For more
- * details see monitor.cc. Note the code below doesn't use ldrex/strex as the code holds the lock
+ * details see monitor.cc. Note the code below doesn't use ldxr/stxr as the code holds the lock
* and can only give away ownership if its suspended.
*/
void Arm64Mir2Lir::GenMonitorExit(int opt_flags, RegLocation rl_src) {
+ // x0/w0 = object
+ // w1 = thin lock thread id
+ // w2 = lock word
+ // TUNING: How much performance we get when we inline this?
+ // Since we've already flush all register.
FlushAllRegs();
- LoadValueDirectFixed(rl_src, rs_x0); // Get obj
+ LoadValueDirectFixed(rl_src, rs_w0); // Get obj
LockCallTemps(); // Prepare for explicit register usage
LIR* null_check_branch = nullptr;
- Load32Disp(rs_rA64_SELF, Thread::ThinLockIdOffset<8>().Int32Value(), rs_x2);
- constexpr bool kArchVariantHasGoodBranchPredictor = false; // TODO: true if cortex-A15.
- if (kArchVariantHasGoodBranchPredictor) {
- if ((opt_flags & MIR_IGNORE_NULL_CHECK) && !(cu_->disable_opt & (1 << kNullCheckElimination))) {
- null_check_branch = nullptr; // No null check.
- } else {
- // If the null-check fails its handled by the slow-path to reduce exception related meta-data.
- if (Runtime::Current()->ExplicitNullChecks()) {
- null_check_branch = OpCmpImmBranch(kCondEq, rs_x0, 0, NULL);
- }
- }
- Load32Disp(rs_x0, mirror::Object::MonitorOffset().Int32Value(), rs_x1);
- MarkPossibleNullPointerException(opt_flags);
- LoadConstantNoClobber(rs_x3, 0);
- LIR* slow_unlock_branch = OpCmpBranch(kCondNe, rs_x1, rs_x2, NULL);
- GenMemBarrier(kStoreLoad);
- Store32Disp(rs_x0, mirror::Object::MonitorOffset().Int32Value(), rs_x3);
- LIR* unlock_success_branch = OpUnconditionalBranch(NULL);
-
- LIR* slow_path_target = NewLIR0(kPseudoTargetLabel);
- slow_unlock_branch->target = slow_path_target;
- if (null_check_branch != nullptr) {
- null_check_branch->target = slow_path_target;
- }
- // TODO: move to a slow path.
- // Go expensive route - artUnlockObjectFromCode(obj);
- LoadWordDisp(rs_rA64_SELF, QUICK_ENTRYPOINT_OFFSET(8, pUnlockObject).Int32Value(), rs_rA64_LR);
- ClobberCallerSave();
- LIR* call_inst = OpReg(kOpBlx, rs_rA64_LR);
- MarkSafepointPC(call_inst);
-
- LIR* success_target = NewLIR0(kPseudoTargetLabel);
- unlock_success_branch->target = success_target;
+ if ((opt_flags & MIR_IGNORE_NULL_CHECK) && !(cu_->disable_opt & (1 << kNullCheckElimination))) {
+ null_check_branch = nullptr; // No null check.
} else {
- // Explicit null-check as slow-path is entered using an IT.
- GenNullCheck(rs_x0, opt_flags);
- Load32Disp(rs_x0, mirror::Object::MonitorOffset().Int32Value(), rs_x1); // Get lock
- MarkPossibleNullPointerException(opt_flags);
- Load32Disp(rs_rA64_SELF, Thread::ThinLockIdOffset<8>().Int32Value(), rs_x2);
- LoadConstantNoClobber(rs_x3, 0);
- // Is lock unheld on lock or held by us (==thread_id) on unlock?
- OpRegReg(kOpCmp, rs_x1, rs_x2);
- OpIT(kCondEq, "EE");
- Store32Disp/*eq*/(rs_x0, mirror::Object::MonitorOffset().Int32Value(), rs_x3);
- // Go expensive route - UnlockObjectFromCode(obj);
- LoadWordDisp/*ne*/(rs_rA64_SELF, QUICK_ENTRYPOINT_OFFSET(8, pUnlockObject).Int32Value(),
- rs_rA64_LR);
- ClobberCallerSave();
- LIR* call_inst = OpReg(kOpBlx/*ne*/, rs_rA64_LR);
- MarkSafepointPC(call_inst);
- GenMemBarrier(kStoreLoad);
+ // If the null-check fails its handled by the slow-path to reduce exception related meta-data.
+ if (Runtime::Current()->ExplicitNullChecks()) {
+ null_check_branch = OpCmpImmBranch(kCondEq, rs_x0, 0, NULL);
+ }
}
+ Load32Disp(rs_rA64_SELF, Thread::ThinLockIdOffset<8>().Int32Value(), rs_w1);
+ Load32Disp(rs_x0, mirror::Object::MonitorOffset().Int32Value(), rs_w2);
+ MarkPossibleNullPointerException(opt_flags);
+ LIR* slow_unlock_branch = OpCmpBranch(kCondNe, rs_w1, rs_w2, NULL);
+ GenMemBarrier(kStoreLoad);
+ Store32Disp(rs_x0, mirror::Object::MonitorOffset().Int32Value(), rs_xzr);
+ LIR* unlock_success_branch = OpUnconditionalBranch(NULL);
+
+ LIR* slow_path_target = NewLIR0(kPseudoTargetLabel);
+ slow_unlock_branch->target = slow_path_target;
+ if (null_check_branch != nullptr) {
+ null_check_branch->target = slow_path_target;
+ }
+ // TODO: move to a slow path.
+ // Go expensive route - artUnlockObjectFromCode(obj);
+ LoadWordDisp(rs_rA64_SELF, QUICK_ENTRYPOINT_OFFSET(8, pUnlockObject).Int32Value(), rs_rA64_LR);
+ ClobberCallerSave();
+ LIR* call_inst = OpReg(kOpBlx, rs_rA64_LR);
+ MarkSafepointPC(call_inst);
+
+ LIR* success_target = NewLIR0(kPseudoTargetLabel);
+ unlock_success_branch->target = success_target;
}
void Arm64Mir2Lir::GenMoveException(RegLocation rl_dest) {
int ex_offset = Thread::ExceptionOffset<8>().Int32Value();
RegLocation rl_result = EvalLoc(rl_dest, kCoreReg, true);
- RegStorage reset_reg = AllocTemp();
Load32Disp(rs_rA64_SELF, ex_offset, rl_result.reg);
- LoadConstant(reset_reg, 0);
- Store32Disp(rs_rA64_SELF, ex_offset, reset_reg);
- FreeTemp(reset_reg);
+ Store32Disp(rs_rA64_SELF, ex_offset, rs_xzr);
StoreValue(rl_dest, rl_result);
}
diff --git a/compiler/dex/quick/arm64/target_arm64.cc b/compiler/dex/quick/arm64/target_arm64.cc
index 6caacc8..10be0d6 100644
--- a/compiler/dex/quick/arm64/target_arm64.cc
+++ b/compiler/dex/quick/arm64/target_arm64.cc
@@ -38,16 +38,27 @@
rs_f24, rs_f25, rs_f26, rs_f27, rs_f28, rs_f29, rs_f30, rs_f31};
static const RegStorage dp_regs_arr[] =
{rs_d0, rs_d1, rs_d2, rs_d3, rs_d4, rs_d5, rs_d6, rs_d7,
- rs_d8, rs_d9, rs_d10, rs_d11, rs_d12, rs_d13, rs_d14, rs_d15};
+ rs_d8, rs_d9, rs_d10, rs_d11, rs_d12, rs_d13, rs_d14, rs_d15,
+ rs_d16, rs_d17, rs_d18, rs_d19, rs_d20, rs_d21, rs_d22, rs_d23,
+ rs_d24, rs_d25, rs_d26, rs_d27, rs_d28, rs_d29, rs_d30, rs_d31};
static const RegStorage reserved_regs_arr[] =
{rs_rA64_SUSPEND, rs_rA64_SELF, rs_rA64_SP, rs_rA64_LR};
+// TUING: Are there too many temp registers and too less promote target?
+// This definition need to be matched with runtime.cc, quick entry assembly and JNI compiler
+// Note: we are not able to call to C function directly if it un-match C ABI.
+// Currently, rs_rA64_SELF is not a callee save register which does not match C ABI.
static const RegStorage core_temps_arr[] =
- {rs_x0, rs_x1, rs_x2, rs_x3, rs_x12};
+ {rs_x0, rs_x1, rs_x2, rs_x3, rs_x4, rs_x5, rs_x6, rs_x7,
+ rs_x8, rs_x9, rs_x10, rs_x11, rs_x12, rs_x13, rs_x14, rs_x15, rs_x16,
+ rs_x17};
static const RegStorage sp_temps_arr[] =
{rs_f0, rs_f1, rs_f2, rs_f3, rs_f4, rs_f5, rs_f6, rs_f7,
- rs_f8, rs_f9, rs_f10, rs_f11, rs_f12, rs_f13, rs_f14, rs_f15};
+ rs_f16, rs_f17, rs_f18, rs_f19, rs_f20, rs_f21, rs_f22, rs_f23,
+ rs_f24, rs_f25, rs_f26, rs_f27, rs_f28, rs_f29, rs_f30, rs_f31};
static const RegStorage dp_temps_arr[] =
- {rs_d0, rs_d1, rs_d2, rs_d3, rs_d4, rs_d5, rs_d6, rs_d7};
+ {rs_d0, rs_d1, rs_d2, rs_d3, rs_d4, rs_d5, rs_d6, rs_d7,
+ rs_d16, rs_d17, rs_d18, rs_d19, rs_d20, rs_d21, rs_d22, rs_d23,
+ rs_d24, rs_d25, rs_d26, rs_d27, rs_d28, rs_d29, rs_d30, rs_d31};
static const std::vector<RegStorage> core_regs(core_regs_arr,
core_regs_arr + arraysize(core_regs_arr));
@@ -877,12 +888,13 @@
rl_src.home = false;
MarkLive(rl_src);
- // TODO(Arm64): compress the Method pointer?
- StoreValueWide(rl_method, rl_src);
+ // rl_method might be 32-bit, but ArtMethod* on stack is 64-bit, so always flush it.
+ StoreWordDisp(TargetReg(kSp), 0, TargetReg(kArg0));
- // If Method* has been promoted, explicitly flush
+ // If Method* has been promoted, load it,
+ // otherwise, rl_method is the 32-bit value on [sp], and has already been loaded.
if (rl_method.location == kLocPhysReg) {
- StoreWordDisp(TargetReg(kSp), 0, TargetReg(kArg0));
+ StoreValue(rl_method, rl_src);
}
if (cu_->num_ins == 0) {
diff --git a/compiler/dex/verified_method.cc b/compiler/dex/verified_method.cc
index 0f812a4..e19f3cf 100644
--- a/compiler/dex/verified_method.cc
+++ b/compiler/dex/verified_method.cc
@@ -34,7 +34,7 @@
#include "mirror/dex_cache-inl.h"
#include "mirror/object.h"
#include "mirror/object-inl.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "verifier/dex_gc_map.h"
#include "verifier/method_verifier.h"
#include "verifier/method_verifier-inl.h"
diff --git a/compiler/driver/compiler_driver_test.cc b/compiler/driver/compiler_driver_test.cc
index 113594a..fe3a4e6 100644
--- a/compiler/driver/compiler_driver_test.cc
+++ b/compiler/driver/compiler_driver_test.cc
@@ -19,7 +19,7 @@
#include <stdint.h>
#include <stdio.h>
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "class_linker.h"
#include "common_compiler_test.h"
#include "dex_file.h"
diff --git a/compiler/elf_fixup.cc b/compiler/elf_fixup.cc
index 6fd4a73..571a091 100644
--- a/compiler/elf_fixup.cc
+++ b/compiler/elf_fixup.cc
@@ -22,7 +22,7 @@
#include "base/stringprintf.h"
#include "elf_file.h"
#include "elf_writer.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/compiler/elf_stripper.cc b/compiler/elf_stripper.cc
index 42291b2..b0fa63c 100644
--- a/compiler/elf_stripper.cc
+++ b/compiler/elf_stripper.cc
@@ -20,7 +20,7 @@
#include <sys/types.h>
#include <vector>
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "base/logging.h"
#include "elf_file.h"
#include "elf_utils.h"
diff --git a/compiler/elf_writer_mclinker.h b/compiler/elf_writer_mclinker.h
index 13757ed..3c1a47b 100644
--- a/compiler/elf_writer_mclinker.h
+++ b/compiler/elf_writer_mclinker.h
@@ -19,7 +19,7 @@
#include "elf_writer.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "safe_map.h"
namespace mcld {
diff --git a/compiler/image_test.cc b/compiler/image_test.cc
index 7c5741b..5a79542 100644
--- a/compiler/image_test.cc
+++ b/compiler/image_test.cc
@@ -27,7 +27,7 @@
#include "lock_word.h"
#include "mirror/object-inl.h"
#include "signal_catcher.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "utils.h"
#include "vector_output_stream.h"
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index d855eee..20a66d4 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -52,7 +52,7 @@
#include "runtime.h"
#include "scoped_thread_state_change.h"
#include "handle_scope-inl.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "utils.h"
using ::art::mirror::ArtField;
diff --git a/compiler/image_writer.h b/compiler/image_writer.h
index 7e22a96..f8df2bb 100644
--- a/compiler/image_writer.h
+++ b/compiler/image_writer.h
@@ -30,7 +30,7 @@
#include "os.h"
#include "safe_map.h"
#include "gc/space/space.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/compiler/jni/jni_compiler_test.cc b/compiler/jni/jni_compiler_test.cc
index 6035689..561d00f 100644
--- a/compiler/jni/jni_compiler_test.cc
+++ b/compiler/jni/jni_compiler_test.cc
@@ -31,7 +31,7 @@
#include "ScopedLocalRef.h"
#include "scoped_thread_state_change.h"
#include "thread.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
extern "C" JNIEXPORT jint JNICALL Java_MyClassNatives_bar(JNIEnv*, jobject, jint count) {
return count + 1;
diff --git a/compiler/jni/quick/jni_compiler.cc b/compiler/jni/quick/jni_compiler.cc
index 20f9f4b..02d6fa5 100644
--- a/compiler/jni/quick/jni_compiler.cc
+++ b/compiler/jni/quick/jni_compiler.cc
@@ -33,7 +33,7 @@
#include "utils/mips/managed_register_mips.h"
#include "utils/x86/managed_register_x86.h"
#include "thread.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#define __ jni_asm->
diff --git a/compiler/oat_writer.h b/compiler/oat_writer.h
index 85c9b47..7a41d87 100644
--- a/compiler/oat_writer.h
+++ b/compiler/oat_writer.h
@@ -26,7 +26,7 @@
#include "oat.h"
#include "mirror/class.h"
#include "safe_map.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc
index a7604be..b9c1164 100644
--- a/compiler/optimizing/graph_visualizer.cc
+++ b/compiler/optimizing/graph_visualizer.cc
@@ -188,6 +188,23 @@
printer.EndTag("compilation");
}
+HGraphVisualizer::HGraphVisualizer(std::ostream* output,
+ HGraph* graph,
+ const char* name)
+ : output_(output), graph_(graph), is_enabled_(false) {
+ if (output == nullptr) {
+ return;
+ }
+
+ is_enabled_ = true;
+ HGraphVisualizerPrinter printer(graph, *output_);
+ printer.StartTag("compilation");
+ printer.PrintProperty("name", name);
+ printer.PrintProperty("method", name);
+ printer.PrintTime("date");
+ printer.EndTag("compilation");
+}
+
void HGraphVisualizer::DumpGraph(const char* pass_name) {
if (!is_enabled_) {
return;
diff --git a/compiler/optimizing/graph_visualizer.h b/compiler/optimizing/graph_visualizer.h
index 433d55d..2b88e65 100644
--- a/compiler/optimizing/graph_visualizer.h
+++ b/compiler/optimizing/graph_visualizer.h
@@ -42,6 +42,12 @@
const DexCompilationUnit& cu);
/**
+ * Version of `HGraphVisualizer` for unit testing, that is when a
+ * `DexCompilationUnit` is not available.
+ */
+ HGraphVisualizer(std::ostream* output, HGraph* graph, const char* name);
+
+ /**
* If this visualizer is enabled, emit the compilation information
* in `output_`.
*/
diff --git a/compiler/optimizing/linearize_test.cc b/compiler/optimizing/linearize_test.cc
new file mode 100644
index 0000000..f9ae529
--- /dev/null
+++ b/compiler/optimizing/linearize_test.cc
@@ -0,0 +1,192 @@
+/*
+ * 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.
+ */
+
+#include <fstream>
+
+#include "base/stringprintf.h"
+#include "builder.h"
+#include "dex_file.h"
+#include "dex_instruction.h"
+#include "graph_visualizer.h"
+#include "nodes.h"
+#include "optimizing_unit_test.h"
+#include "pretty_printer.h"
+#include "ssa_builder.h"
+#include "ssa_liveness_analysis.h"
+#include "utils/arena_allocator.h"
+
+#include "gtest/gtest.h"
+
+namespace art {
+
+static void TestCode(const uint16_t* data, const int* expected_order, size_t number_of_blocks) {
+ ArenaPool pool;
+ ArenaAllocator allocator(&pool);
+ HGraphBuilder builder(&allocator);
+ const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
+ HGraph* graph = builder.BuildGraph(*item);
+ ASSERT_NE(graph, nullptr);
+
+ graph->BuildDominatorTree();
+ graph->FindNaturalLoops();
+ SsaLivenessAnalysis liveness(*graph);
+ liveness.Analyze();
+
+ ASSERT_EQ(liveness.GetLinearPostOrder().Size(), number_of_blocks);
+ for (size_t i = 0; i < number_of_blocks; ++i) {
+ ASSERT_EQ(liveness.GetLinearPostOrder().Get(number_of_blocks - i - 1)->GetBlockId(),
+ expected_order[i]);
+ }
+}
+
+TEST(LinearizeTest, CFG1) {
+ // Structure of this graph (+ are back edges)
+ // Block0
+ // |
+ // Block1
+ // |
+ // Block2 ++++++
+ // / \ +
+ // Block5 Block7 +
+ // | | +
+ // Block6 Block3 +
+ // + / \ +
+ // Block4 Block8
+
+ const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
+ Instruction::CONST_4 | 0 | 0,
+ Instruction::IF_EQ, 5,
+ Instruction::IF_EQ, 0xFFFE,
+ Instruction::GOTO | 0xFE00,
+ Instruction::RETURN_VOID);
+
+ const int blocks[] = {0, 1, 2, 7, 3, 4, 8, 5, 6};
+ TestCode(data, blocks, 9);
+}
+
+TEST(LinearizeTest, CFG2) {
+ // Structure of this graph (+ are back edges)
+ // Block0
+ // |
+ // Block1
+ // |
+ // Block2 ++++++
+ // / \ +
+ // Block3 Block7 +
+ // | | +
+ // Block6 Block4 +
+ // + / \ +
+ // Block5 Block8
+
+ const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
+ Instruction::CONST_4 | 0 | 0,
+ Instruction::IF_EQ, 3,
+ Instruction::RETURN_VOID,
+ Instruction::IF_EQ, 0xFFFD,
+ Instruction::GOTO | 0xFE00);
+
+ const int blocks[] = {0, 1, 2, 7, 4, 5, 8, 3, 6};
+ TestCode(data, blocks, 9);
+}
+
+TEST(LinearizeTest, CFG3) {
+ // Structure of this graph (+ are back edges)
+ // Block0
+ // |
+ // Block1
+ // |
+ // Block2 ++++++
+ // / \ +
+ // Block3 Block8 +
+ // | | +
+ // Block7 Block5 +
+ // / + \ +
+ // Block6 + Block9
+ // | +
+ // Block4 ++
+ const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
+ Instruction::CONST_4 | 0 | 0,
+ Instruction::IF_EQ, 4,
+ Instruction::RETURN_VOID,
+ Instruction::GOTO | 0x0100,
+ Instruction::IF_EQ, 0xFFFC,
+ Instruction::GOTO | 0xFD00);
+
+ const int blocks[] = {0, 1, 2, 8, 5, 6, 4, 9, 3, 7};
+ TestCode(data, blocks, 10);
+}
+
+TEST(LinearizeTest, CFG4) {
+ /* Structure of this graph (+ are back edges)
+ // Block0
+ // |
+ // Block1
+ // |
+ // Block2
+ // / + \
+ // Block6 + Block8
+ // | + |
+ // Block7 + Block3 +++++++
+ // + / \ +
+ // Block9 Block10 +
+ // | +
+ // Block4 +
+ // + / \ +
+ // Block5 Block11
+ */
+ const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
+ Instruction::CONST_4 | 0 | 0,
+ Instruction::IF_EQ, 7,
+ Instruction::IF_EQ, 0xFFFE,
+ Instruction::IF_EQ, 0xFFFE,
+ Instruction::GOTO | 0xFE00,
+ Instruction::RETURN_VOID);
+
+ const int blocks[] = {0, 1, 2, 8, 3, 10, 4, 5, 11, 9, 6, 7};
+ TestCode(data, blocks, 12);
+}
+
+TEST(LinearizeTest, CFG5) {
+ /* Structure of this graph (+ are back edges)
+ // Block0
+ // |
+ // Block1
+ // |
+ // Block2
+ // / + \
+ // Block3 + Block8
+ // | + |
+ // Block7 + Block4 +++++++
+ // + / \ +
+ // Block9 Block10 +
+ // | +
+ // Block5 +
+ // +/ \ +
+ // Block6 Block11
+ */
+ const uint16_t data[] = ONE_REGISTER_CODE_ITEM(
+ Instruction::CONST_4 | 0 | 0,
+ Instruction::IF_EQ, 3,
+ Instruction::RETURN_VOID,
+ Instruction::IF_EQ, 0xFFFD,
+ Instruction::IF_EQ, 0xFFFE,
+ Instruction::GOTO | 0xFE00);
+
+ const int blocks[] = {0, 1, 2, 8, 4, 10, 5, 6, 11, 9, 3, 7};
+ TestCode(data, blocks, 12);
+}
+
+} // namespace art
diff --git a/compiler/optimizing/liveness_test.cc b/compiler/optimizing/liveness_test.cc
index d665ab9..53e7bbe 100644
--- a/compiler/optimizing/liveness_test.cc
+++ b/compiler/optimizing/liveness_test.cc
@@ -35,6 +35,7 @@
ASSERT_NE(graph, nullptr);
graph->BuildDominatorTree();
graph->TransformToSSA();
+ graph->FindNaturalLoops();
SsaLivenessAnalysis liveness(*graph);
liveness.Analyze();
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 27b87ca..1085c10 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -445,7 +445,7 @@
bool HasUses() const { return uses_ != nullptr || env_uses_ != nullptr; }
size_t NumberOfUses() const {
- // TODO: Optimize this method if it is used outside of the HGraphTracer.
+ // TODO: Optimize this method if it is used outside of the HGraphVisualizer.
size_t result = 0;
HUseListNode<HInstruction>* current = uses_;
while (current != nullptr) {
diff --git a/compiler/optimizing/pretty_printer.h b/compiler/optimizing/pretty_printer.h
index dfeafe7..a7727c0 100644
--- a/compiler/optimizing/pretty_printer.h
+++ b/compiler/optimizing/pretty_printer.h
@@ -100,6 +100,47 @@
DISALLOW_COPY_AND_ASSIGN(HPrettyPrinter);
};
+class StringPrettyPrinter : public HPrettyPrinter {
+ public:
+ explicit StringPrettyPrinter(HGraph* graph)
+ : HPrettyPrinter(graph), str_(""), current_block_(nullptr) { }
+
+ virtual void PrintInt(int value) {
+ str_ += StringPrintf("%d", value);
+ }
+
+ virtual void PrintString(const char* value) {
+ str_ += value;
+ }
+
+ virtual void PrintNewLine() {
+ str_ += '\n';
+ }
+
+ void Clear() { str_.clear(); }
+
+ std::string str() const { return str_; }
+
+ virtual void VisitBasicBlock(HBasicBlock* block) {
+ current_block_ = block;
+ HPrettyPrinter::VisitBasicBlock(block);
+ }
+
+ virtual void VisitGoto(HGoto* gota) {
+ PrintString(" ");
+ PrintInt(gota->GetId());
+ PrintString(": Goto ");
+ PrintInt(current_block_->GetSuccessors().Get(0)->GetBlockId());
+ PrintNewLine();
+ }
+
+ private:
+ std::string str_;
+ HBasicBlock* current_block_;
+
+ DISALLOW_COPY_AND_ASSIGN(StringPrettyPrinter);
+};
+
} // namespace art
#endif // ART_COMPILER_OPTIMIZING_PRETTY_PRINTER_H_
diff --git a/compiler/optimizing/pretty_printer_test.cc b/compiler/optimizing/pretty_printer_test.cc
index 006349c..7e604e9 100644
--- a/compiler/optimizing/pretty_printer_test.cc
+++ b/compiler/optimizing/pretty_printer_test.cc
@@ -27,47 +27,6 @@
namespace art {
-class StringPrettyPrinter : public HPrettyPrinter {
- public:
- explicit StringPrettyPrinter(HGraph* graph)
- : HPrettyPrinter(graph), str_(""), current_block_(nullptr) { }
-
- virtual void PrintInt(int value) {
- str_ += StringPrintf("%d", value);
- }
-
- virtual void PrintString(const char* value) {
- str_ += value;
- }
-
- virtual void PrintNewLine() {
- str_ += '\n';
- }
-
- void Clear() { str_.clear(); }
-
- std::string str() const { return str_; }
-
- virtual void VisitBasicBlock(HBasicBlock* block) {
- current_block_ = block;
- HPrettyPrinter::VisitBasicBlock(block);
- }
-
- virtual void VisitGoto(HGoto* gota) {
- PrintString(" ");
- PrintInt(gota->GetId());
- PrintString(": Goto ");
- PrintInt(current_block_->GetSuccessors().Get(0)->GetBlockId());
- PrintNewLine();
- }
-
- private:
- std::string str_;
- HBasicBlock* current_block_;
-
- DISALLOW_COPY_AND_ASSIGN(StringPrettyPrinter);
-};
-
static void TestCode(const uint16_t* data, const char* expected) {
ArenaPool pool;
ArenaAllocator allocator(&pool);
diff --git a/compiler/optimizing/ssa_liveness_analysis.cc b/compiler/optimizing/ssa_liveness_analysis.cc
index 7c2ec39..85171aa 100644
--- a/compiler/optimizing/ssa_liveness_analysis.cc
+++ b/compiler/optimizing/ssa_liveness_analysis.cc
@@ -20,13 +20,92 @@
namespace art {
void SsaLivenessAnalysis::Analyze() {
+ LinearizeGraph();
NumberInstructions();
ComputeSets();
}
+static bool IsLoopExit(HLoopInformation* current, HLoopInformation* to) {
+ // `to` is either not part of a loop, or `current` is an inner loop of `to`.
+ return to == nullptr || (current != to && current->IsIn(*to));
+}
+
+static bool IsLoop(HLoopInformation* info) {
+ return info != nullptr;
+}
+
+static bool InSameLoop(HLoopInformation* first_loop, HLoopInformation* second_loop) {
+ return first_loop == second_loop;
+}
+
+static bool IsInnerLoop(HLoopInformation* outer, HLoopInformation* inner) {
+ return (inner != outer)
+ && (inner != nullptr)
+ && (outer != nullptr)
+ && inner->IsIn(*outer);
+}
+
+static void VisitBlockForLinearization(HBasicBlock* block,
+ GrowableArray<HBasicBlock*>* order,
+ ArenaBitVector* visited) {
+ if (visited->IsBitSet(block->GetBlockId())) {
+ return;
+ }
+ visited->SetBit(block->GetBlockId());
+ size_t number_of_successors = block->GetSuccessors().Size();
+ if (number_of_successors == 0) {
+ // Nothing to do.
+ } else if (number_of_successors == 1) {
+ VisitBlockForLinearization(block->GetSuccessors().Get(0), order, visited);
+ } else {
+ DCHECK_EQ(number_of_successors, 2u);
+ HBasicBlock* first_successor = block->GetSuccessors().Get(0);
+ HBasicBlock* second_successor = block->GetSuccessors().Get(1);
+ HLoopInformation* my_loop = block->GetLoopInformation();
+ HLoopInformation* first_loop = first_successor->GetLoopInformation();
+ HLoopInformation* second_loop = second_successor->GetLoopInformation();
+
+ if (!IsLoop(my_loop)) {
+ // Nothing to do. Current order is fine.
+ } else if (IsLoopExit(my_loop, second_loop) && InSameLoop(my_loop, first_loop)) {
+ // Visit the loop exit first in post order.
+ std::swap(first_successor, second_successor);
+ } else if (IsInnerLoop(my_loop, first_loop) && !IsInnerLoop(my_loop, second_loop)) {
+ // Visit the inner loop last in post order.
+ std::swap(first_successor, second_successor);
+ }
+ VisitBlockForLinearization(first_successor, order, visited);
+ VisitBlockForLinearization(second_successor, order, visited);
+ }
+ order->Add(block);
+}
+
+class HLinearOrderIterator : public ValueObject {
+ public:
+ explicit HLinearOrderIterator(const GrowableArray<HBasicBlock*>& post_order)
+ : post_order_(post_order), index_(post_order.Size()) {}
+
+ bool Done() const { return index_ == 0; }
+ HBasicBlock* Current() const { return post_order_.Get(index_ -1); }
+ void Advance() { --index_; DCHECK_GE(index_, 0U); }
+
+ private:
+ const GrowableArray<HBasicBlock*>& post_order_;
+ size_t index_;
+
+ DISALLOW_COPY_AND_ASSIGN(HLinearOrderIterator);
+};
+
+void SsaLivenessAnalysis::LinearizeGraph() {
+ // For simplicity of the implementation, we create post linear order. The order for
+ // computing live ranges is the reverse of that order.
+ ArenaBitVector visited(graph_.GetArena(), graph_.GetBlocks().Size(), false);
+ VisitBlockForLinearization(graph_.GetEntryBlock(), &linear_post_order_, &visited);
+}
+
void SsaLivenessAnalysis::NumberInstructions() {
int ssa_index = 0;
- for (HReversePostOrderIterator it(graph_); !it.Done(); it.Advance()) {
+ for (HLinearOrderIterator it(linear_post_order_); !it.Done(); it.Advance()) {
HBasicBlock* block = it.Current();
for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) {
@@ -47,7 +126,7 @@
}
void SsaLivenessAnalysis::ComputeSets() {
- for (HReversePostOrderIterator it(graph_); !it.Done(); it.Advance()) {
+ for (HLinearOrderIterator it(linear_post_order_); !it.Done(); it.Advance()) {
HBasicBlock* block = it.Current();
block_infos_.Put(
block->GetBlockId(),
diff --git a/compiler/optimizing/ssa_liveness_analysis.h b/compiler/optimizing/ssa_liveness_analysis.h
index 6a901d1..b8695ba 100644
--- a/compiler/optimizing/ssa_liveness_analysis.h
+++ b/compiler/optimizing/ssa_liveness_analysis.h
@@ -48,6 +48,7 @@
public:
explicit SsaLivenessAnalysis(const HGraph& graph)
: graph_(graph),
+ linear_post_order_(graph.GetArena(), graph.GetBlocks().Size()),
block_infos_(graph.GetArena(), graph.GetBlocks().Size()),
number_of_ssa_values_(0) {
block_infos_.SetSize(graph.GetBlocks().Size());
@@ -67,7 +68,17 @@
return &block_infos_.Get(block.GetBlockId())->kill_;
}
+ const GrowableArray<HBasicBlock*>& GetLinearPostOrder() const {
+ return linear_post_order_;
+ }
+
private:
+ // Linearize the graph so that:
+ // (1): a block is always after its dominator,
+ // (2): blocks of loops are contiguous.
+ // This creates a natural and efficient ordering when visualizing live ranges.
+ void LinearizeGraph();
+
// Give an SSA number to each instruction that defines a value used by another instruction.
void NumberInstructions();
@@ -90,6 +101,7 @@
bool UpdateLiveOut(const HBasicBlock& block);
const HGraph& graph_;
+ GrowableArray<HBasicBlock*> linear_post_order_;
GrowableArray<BlockInfo*> block_infos_;
size_t number_of_ssa_values_;
diff --git a/compiler/optimizing/ssa_test.cc b/compiler/optimizing/ssa_test.cc
index 415d146..d104619 100644
--- a/compiler/optimizing/ssa_test.cc
+++ b/compiler/optimizing/ssa_test.cc
@@ -28,9 +28,9 @@
namespace art {
-class StringPrettyPrinter : public HPrettyPrinter {
+class SsaPrettyPrinter : public HPrettyPrinter {
public:
- explicit StringPrettyPrinter(HGraph* graph) : HPrettyPrinter(graph), str_("") {}
+ explicit SsaPrettyPrinter(HGraph* graph) : HPrettyPrinter(graph), str_("") {}
virtual void PrintInt(int value) {
str_ += StringPrintf("%d", value);
@@ -59,7 +59,7 @@
private:
std::string str_;
- DISALLOW_COPY_AND_ASSIGN(StringPrettyPrinter);
+ DISALLOW_COPY_AND_ASSIGN(SsaPrettyPrinter);
};
static void ReNumberInstructions(HGraph* graph) {
@@ -82,11 +82,12 @@
const DexFile::CodeItem* item = reinterpret_cast<const DexFile::CodeItem*>(data);
HGraph* graph = builder.BuildGraph(*item);
ASSERT_NE(graph, nullptr);
+
graph->BuildDominatorTree();
graph->TransformToSSA();
ReNumberInstructions(graph);
- StringPrettyPrinter printer(graph);
+ SsaPrettyPrinter printer(graph);
printer.VisitInsertionOrder();
ASSERT_STREQ(expected, printer.str().c_str());
diff --git a/compiler/utils/arm64/assembler_arm64.h b/compiler/utils/arm64/assembler_arm64.h
index c866b29..0f4a9a4 100644
--- a/compiler/utils/arm64/assembler_arm64.h
+++ b/compiler/utils/arm64/assembler_arm64.h
@@ -26,7 +26,7 @@
#include "utils/assembler.h"
#include "offsets.h"
#include "utils.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "a64/macro-assembler-a64.h"
#include "a64/disasm-a64.h"
diff --git a/dalvikvm/Android.mk b/dalvikvm/Android.mk
index e99c76f..e7ed9a7 100644
--- a/dalvikvm/Android.mk
+++ b/dalvikvm/Android.mk
@@ -16,7 +16,7 @@
LOCAL_PATH := $(call my-dir)
-dalvikvm_cflags := -Wall -Werror -Wextra
+dalvikvm_cflags := -Wall -Werror -Wextra -std=gnu++11
include $(CLEAR_VARS)
LOCAL_MODULE := dalvikvm
@@ -24,22 +24,29 @@
LOCAL_CPP_EXTENSION := cc
LOCAL_SRC_FILES := dalvikvm.cc
LOCAL_CFLAGS := $(dalvikvm_cflags)
+LOCAL_C_INCLUDES := art/runtime
LOCAL_SHARED_LIBRARIES := libdl libnativehelper
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_MULTILIB := both
-LOCAL_MODULE_STEM_32 := dalvikvm
+LOCAL_MODULE_STEM_32 := dalvikvm32
LOCAL_MODULE_STEM_64 := dalvikvm64
include art/build/Android.libcxx.mk
include $(BUILD_EXECUTABLE)
+
+# create symlink for the primary version target.
+include $(BUILD_SYSTEM)/executable_prefer_symlink.mk
+
ART_TARGET_EXECUTABLES += $(TARGET_OUT_EXECUTABLES)/$(LOCAL_MODULE)
ifeq ($(WITH_HOST_DALVIK),true)
include $(CLEAR_VARS)
LOCAL_MODULE := dalvikvm
LOCAL_MODULE_TAGS := optional
+LOCAL_CLANG := true
LOCAL_CPP_EXTENSION := cc
LOCAL_SRC_FILES := dalvikvm.cc
LOCAL_CFLAGS := $(dalvikvm_cflags)
+LOCAL_C_INCLUDES := art/runtime
LOCAL_SHARED_LIBRARIES := libnativehelper
LOCAL_LDFLAGS := -ldl -lpthread
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
diff --git a/dalvikvm/dalvikvm.cc b/dalvikvm/dalvikvm.cc
index 8d71a7c..582adc0 100644
--- a/dalvikvm/dalvikvm.cc
+++ b/dalvikvm/dalvikvm.cc
@@ -24,7 +24,7 @@
#include "JniInvocation.h"
#include "ScopedLocalRef.h"
#include "toStringArray.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/runtime/UniquePtrCompat.h b/runtime/UniquePtrCompat.h
new file mode 100644
index 0000000..4a45616
--- /dev/null
+++ b/runtime/UniquePtrCompat.h
@@ -0,0 +1,37 @@
+/*
+ * 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_RUNTIME_UNIQUEPTRCOMPAT_H_
+#define ART_RUNTIME_UNIQUEPTRCOMPAT_H_
+
+// Stlport doesn't declare std::unique_ptr. UniquePtr.h declares an incompatible std::swap
+// prototype with libc++. This compatibility header file resolves differences between the two, in
+// the future UniquePtr will become std::unique_ptr.
+
+#ifdef ART_WITH_STLPORT
+
+#include "UniquePtr.h"
+
+#else // ART_WITH_STLPORT
+
+#include <memory>
+
+template <typename T>
+using UniquePtr = typename std::unique_ptr<T>;
+
+#endif // ART_WITH_STLPORT
+
+#endif // ART_RUNTIME_UNIQUEPTRCOMPAT_H_
diff --git a/runtime/barrier.h b/runtime/barrier.h
index 0c7fd87..d3e6bae 100644
--- a/runtime/barrier.h
+++ b/runtime/barrier.h
@@ -18,7 +18,7 @@
#define ART_RUNTIME_BARRIER_H_
#include "base/mutex.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/runtime/barrier_test.cc b/runtime/barrier_test.cc
index 7d32338..a02c4c7 100644
--- a/runtime/barrier_test.cc
+++ b/runtime/barrier_test.cc
@@ -22,7 +22,7 @@
#include "common_runtime_test.h"
#include "mirror/object_array-inl.h"
#include "thread_pool.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
class CheckWaitTask : public Task {
diff --git a/runtime/base/bit_vector_test.cc b/runtime/base/bit_vector_test.cc
index 2ff55cb..990d1db 100644
--- a/runtime/base/bit_vector_test.cc
+++ b/runtime/base/bit_vector_test.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "bit_vector.h"
#include "gtest/gtest.h"
diff --git a/runtime/base/histogram_test.cc b/runtime/base/histogram_test.cc
index 966b97f..d72ae47 100644
--- a/runtime/base/histogram_test.cc
+++ b/runtime/base/histogram_test.cc
@@ -16,7 +16,7 @@
#include "gtest/gtest.h"
#include "histogram-inl.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include <sstream>
diff --git a/runtime/base/logging.cc b/runtime/base/logging.cc
index 730a2c2..b6c6b9b 100644
--- a/runtime/base/logging.cc
+++ b/runtime/base/logging.cc
@@ -19,7 +19,7 @@
#include "base/mutex.h"
#include "runtime.h"
#include "thread-inl.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "utils.h"
namespace art {
diff --git a/runtime/base/logging.h b/runtime/base/logging.h
index 6944278..7800cfe 100644
--- a/runtime/base/logging.h
+++ b/runtime/base/logging.h
@@ -25,7 +25,7 @@
#include <vector>
#include "base/macros.h"
#include "log_severity.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#define CHECK(x) \
if (UNLIKELY(!(x))) \
diff --git a/runtime/base/unix_file/random_access_file_test.h b/runtime/base/unix_file/random_access_file_test.h
index 8a6605e..67e8c22 100644
--- a/runtime/base/unix_file/random_access_file_test.h
+++ b/runtime/base/unix_file/random_access_file_test.h
@@ -22,7 +22,7 @@
#include <string>
#include "common_runtime_test.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace unix_file {
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 9034560..c7f3a20 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -62,7 +62,7 @@
#include "scoped_thread_state_change.h"
#include "handle_scope-inl.h"
#include "thread.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "utils.h"
#include "verifier/method_verifier.h"
#include "well_known_classes.h"
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index 0db08aa..9970dd5 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -18,7 +18,7 @@
#include <string>
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "class_linker-inl.h"
#include "common_runtime_test.h"
#include "dex_file.h"
diff --git a/runtime/common_runtime_test.h b/runtime/common_runtime_test.h
index 79d3690..d7a1667 100644
--- a/runtime/common_runtime_test.h
+++ b/runtime/common_runtime_test.h
@@ -47,7 +47,7 @@
#include "ScopedLocalRef.h"
#include "thread.h"
#include "utils.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "verifier/method_verifier.h"
#include "verifier/method_verifier-inl.h"
#include "well_known_classes.h"
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index edf54be..f6b4891 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -2809,6 +2809,7 @@
}
case DeoptimizationRequest::kFullUndeoptimization: {
DCHECK(req.method == nullptr);
+ DCHECK_GT(full_deoptimization_event_count_, 0U);
--full_deoptimization_event_count_;
if (full_deoptimization_event_count_ == 0) {
VLOG(jdwp) << "Queue request #" << deoptimization_requests_.size()
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index f3d4621..26b7d07 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -39,7 +39,7 @@
#include "ScopedFd.h"
#include "handle_scope-inl.h"
#include "thread.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "utf-inl.h"
#include "utils.h"
#include "well_known_classes.h"
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index cfa2555..0146f31 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -28,7 +28,7 @@
#include "mem_map.h"
#include "modifiers.h"
#include "safe_map.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/runtime/dex_file_test.cc b/runtime/dex_file_test.cc
index 9b6859a..86c282e 100644
--- a/runtime/dex_file_test.cc
+++ b/runtime/dex_file_test.cc
@@ -16,7 +16,7 @@
#include "dex_file.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "common_runtime_test.h"
namespace art {
diff --git a/runtime/dex_file_verifier.cc b/runtime/dex_file_verifier.cc
index 528e112..d179c8b 100644
--- a/runtime/dex_file_verifier.cc
+++ b/runtime/dex_file_verifier.cc
@@ -22,7 +22,7 @@
#include "dex_file-inl.h"
#include "leb128.h"
#include "safe_map.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "utf-inl.h"
#include "utils.h"
diff --git a/runtime/dex_instruction_visitor_test.cc b/runtime/dex_instruction_visitor_test.cc
index 8f42b0c..99ad3ed 100644
--- a/runtime/dex_instruction_visitor_test.cc
+++ b/runtime/dex_instruction_visitor_test.cc
@@ -18,7 +18,7 @@
#include <iostream>
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "gtest/gtest.h"
namespace art {
diff --git a/runtime/elf_file.h b/runtime/elf_file.h
index d2a044e..138147b 100644
--- a/runtime/elf_file.h
+++ b/runtime/elf_file.h
@@ -25,7 +25,7 @@
#include "elf_utils.h"
#include "mem_map.h"
#include "os.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/runtime/exception_test.cc b/runtime/exception_test.cc
index 91a0176..37ad9e5 100644
--- a/runtime/exception_test.cc
+++ b/runtime/exception_test.cc
@@ -27,7 +27,7 @@
#include "scoped_thread_state_change.h"
#include "handle_scope-inl.h"
#include "thread.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "vmap_table.h"
namespace art {
diff --git a/runtime/gc/accounting/atomic_stack.h b/runtime/gc/accounting/atomic_stack.h
index c79b586..7d8b584 100644
--- a/runtime/gc/accounting/atomic_stack.h
+++ b/runtime/gc/accounting/atomic_stack.h
@@ -23,7 +23,7 @@
#include "atomic.h"
#include "base/logging.h"
#include "base/macros.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "mem_map.h"
#include "utils.h"
diff --git a/runtime/gc/accounting/card_table.h b/runtime/gc/accounting/card_table.h
index 8d5dc07..17e62a6 100644
--- a/runtime/gc/accounting/card_table.h
+++ b/runtime/gc/accounting/card_table.h
@@ -20,7 +20,7 @@
#include "base/mutex.h"
#include "globals.h"
#include "mem_map.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/runtime/gc/accounting/mod_union_table.cc b/runtime/gc/accounting/mod_union_table.cc
index 7cddaf4..ef5653a 100644
--- a/runtime/gc/accounting/mod_union_table.cc
+++ b/runtime/gc/accounting/mod_union_table.cc
@@ -30,7 +30,7 @@
#include "mirror/object_array-inl.h"
#include "space_bitmap-inl.h"
#include "thread.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
using ::art::mirror::Object;
diff --git a/runtime/gc/accounting/remembered_set.cc b/runtime/gc/accounting/remembered_set.cc
index bbbd1ed..1def334 100644
--- a/runtime/gc/accounting/remembered_set.cc
+++ b/runtime/gc/accounting/remembered_set.cc
@@ -30,7 +30,7 @@
#include "mirror/object_array-inl.h"
#include "space_bitmap-inl.h"
#include "thread.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
namespace gc {
diff --git a/runtime/gc/accounting/space_bitmap-inl.h b/runtime/gc/accounting/space_bitmap-inl.h
index 646fce6..a439462 100644
--- a/runtime/gc/accounting/space_bitmap-inl.h
+++ b/runtime/gc/accounting/space_bitmap-inl.h
@@ -28,7 +28,7 @@
#include "mirror/object_array-inl.h"
#include "object_utils.h"
#include "space_bitmap-inl.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "utils.h"
namespace art {
diff --git a/runtime/gc/accounting/space_bitmap.h b/runtime/gc/accounting/space_bitmap.h
index a805809..1ccebf5 100644
--- a/runtime/gc/accounting/space_bitmap.h
+++ b/runtime/gc/accounting/space_bitmap.h
@@ -22,7 +22,7 @@
#include "globals.h"
#include "mem_map.h"
#include "object_callbacks.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include <limits.h>
#include <set>
diff --git a/runtime/gc/accounting/space_bitmap_test.cc b/runtime/gc/accounting/space_bitmap_test.cc
index 972f94d..71db44b 100644
--- a/runtime/gc/accounting/space_bitmap_test.cc
+++ b/runtime/gc/accounting/space_bitmap_test.cc
@@ -21,7 +21,7 @@
#include "common_runtime_test.h"
#include "globals.h"
#include "space_bitmap-inl.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
namespace gc {
diff --git a/runtime/gc/allocator/rosalloc.h b/runtime/gc/allocator/rosalloc.h
index 8557f1b..9ea4306 100644
--- a/runtime/gc/allocator/rosalloc.h
+++ b/runtime/gc/allocator/rosalloc.h
@@ -28,7 +28,7 @@
#include "base/logging.h"
#include "globals.h"
#include "mem_map.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "utils.h"
// Ensure we have an unordered_set until we have worked out C++ library issues.
diff --git a/runtime/gc/collector/mark_sweep.h b/runtime/gc/collector/mark_sweep.h
index cfb0b5e..fd79bf6 100644
--- a/runtime/gc/collector/mark_sweep.h
+++ b/runtime/gc/collector/mark_sweep.h
@@ -26,7 +26,7 @@
#include "immune_region.h"
#include "object_callbacks.h"
#include "offsets.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/runtime/gc/collector/semi_space.h b/runtime/gc/collector/semi_space.h
index 4b1ecc4..dacb5ae 100644
--- a/runtime/gc/collector/semi_space.h
+++ b/runtime/gc/collector/semi_space.h
@@ -25,7 +25,7 @@
#include "immune_region.h"
#include "object_callbacks.h"
#include "offsets.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 4642a98..b4c2d14 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -64,7 +64,7 @@
#include "scoped_thread_state_change.h"
#include "handle_scope-inl.h"
#include "thread_list.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "well_known_classes.h"
namespace art {
diff --git a/runtime/gc/space/large_object_space.cc b/runtime/gc/space/large_object_space.cc
index 554fbbe..6c851af 100644
--- a/runtime/gc/space/large_object_space.cc
+++ b/runtime/gc/space/large_object_space.cc
@@ -20,7 +20,7 @@
#include "base/logging.h"
#include "base/mutex-inl.h"
#include "base/stl_util.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "image.h"
#include "os.h"
#include "space-inl.h"
diff --git a/runtime/gc/space/space.h b/runtime/gc/space/space.h
index dcf5357..343bc29 100644
--- a/runtime/gc/space/space.h
+++ b/runtime/gc/space/space.h
@@ -19,7 +19,7 @@
#include <string>
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "base/macros.h"
#include "base/mutex.h"
#include "gc/accounting/space_bitmap.h"
diff --git a/runtime/gc/space/space_test.h b/runtime/gc/space/space_test.h
index ce101e4..407d362 100644
--- a/runtime/gc/space/space_test.h
+++ b/runtime/gc/space/space_test.h
@@ -23,7 +23,7 @@
#include "common_runtime_test.h"
#include "globals.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "mirror/array-inl.h"
#include "mirror/object-inl.h"
diff --git a/runtime/intern_table.cc b/runtime/intern_table.cc
index dfc82dd..2a8cc63 100644
--- a/runtime/intern_table.cc
+++ b/runtime/intern_table.cc
@@ -22,7 +22,7 @@
#include "mirror/object-inl.h"
#include "mirror/string.h"
#include "thread.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "utf.h"
namespace art {
diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc
index 74f386c..5b7dee1d 100644
--- a/runtime/interpreter/interpreter_goto_table_impl.cc
+++ b/runtime/interpreter/interpreter_goto_table_impl.cc
@@ -257,6 +257,9 @@
instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
shadow_frame.GetMethod(), dex_pc,
result);
+ } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
+ instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
+ shadow_frame.GetMethod(), dex_pc);
}
return result;
}
@@ -273,6 +276,9 @@
instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
shadow_frame.GetMethod(), dex_pc,
result);
+ } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
+ instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
+ shadow_frame.GetMethod(), dex_pc);
}
return result;
}
@@ -290,6 +296,9 @@
instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
shadow_frame.GetMethod(), dex_pc,
result);
+ } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
+ instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
+ shadow_frame.GetMethod(), dex_pc);
}
return result;
}
@@ -306,6 +315,9 @@
instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
shadow_frame.GetMethod(), dex_pc,
result);
+ } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
+ instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
+ shadow_frame.GetMethod(), dex_pc);
}
return result;
}
@@ -340,6 +352,9 @@
instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
shadow_frame.GetMethod(), dex_pc,
result);
+ } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
+ instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
+ shadow_frame.GetMethod(), dex_pc);
}
return result;
}
@@ -2389,6 +2404,9 @@
// Create alternative instruction handlers dedicated to instrumentation.
// Return instructions must not call Instrumentation::DexPcMovedEvent since they already call
// Instrumentation::MethodExited. This is to avoid posting debugger events twice for this location.
+// Note: we do not use the kReturn instruction flag here (to test the instruction is a return). The
+// compiler seems to not evaluate "(Instruction::FlagsOf(Instruction::code) & kReturn) != 0" to
+// a constant condition that would remove the "if" statement so the test is free.
#define INSTRUMENTATION_INSTRUCTION_HANDLER(o, code, n, f, r, i, a, v) \
alt_op_##code: { \
if (Instruction::code != Instruction::RETURN_VOID && \
diff --git a/runtime/interpreter/interpreter_switch_impl.cc b/runtime/interpreter/interpreter_switch_impl.cc
index 97c216d..859cfc4 100644
--- a/runtime/interpreter/interpreter_switch_impl.cc
+++ b/runtime/interpreter/interpreter_switch_impl.cc
@@ -184,6 +184,9 @@
instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
shadow_frame.GetMethod(), inst->GetDexPc(insns),
result);
+ } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
+ instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
+ shadow_frame.GetMethod(), dex_pc);
}
return result;
}
@@ -197,6 +200,9 @@
instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
shadow_frame.GetMethod(), inst->GetDexPc(insns),
result);
+ } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
+ instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
+ shadow_frame.GetMethod(), dex_pc);
}
return result;
}
@@ -211,6 +217,9 @@
instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
shadow_frame.GetMethod(), inst->GetDexPc(insns),
result);
+ } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
+ instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
+ shadow_frame.GetMethod(), dex_pc);
}
return result;
}
@@ -224,6 +233,9 @@
instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
shadow_frame.GetMethod(), inst->GetDexPc(insns),
result);
+ } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
+ instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
+ shadow_frame.GetMethod(), dex_pc);
}
return result;
}
@@ -255,6 +267,9 @@
instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
shadow_frame.GetMethod(), inst->GetDexPc(insns),
result);
+ } else if (UNLIKELY(instrumentation->HasDexPcListeners())) {
+ instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
+ shadow_frame.GetMethod(), dex_pc);
}
return result;
}
diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc
index 4843c2b..00be016 100644
--- a/runtime/jdwp/jdwp_handler.cc
+++ b/runtime/jdwp/jdwp_handler.cc
@@ -32,7 +32,7 @@
#include "jdwp/jdwp_priv.h"
#include "runtime.h"
#include "thread-inl.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 21dab8d..3afb149 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -49,7 +49,7 @@
#include "ScopedLocalRef.h"
#include "thread.h"
#include "utf.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "well_known_classes.h"
namespace art {
diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc
index 98b0bbf..5225919 100644
--- a/runtime/mem_map.cc
+++ b/runtime/mem_map.cc
@@ -19,7 +19,7 @@
#include <inttypes.h>
#include <backtrace/BacktraceMap.h>
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "base/stringprintf.h"
#include "ScopedFd.h"
#include "utils.h"
diff --git a/runtime/mem_map_test.cc b/runtime/mem_map_test.cc
index 2b59cd9..b26f563 100644
--- a/runtime/mem_map_test.cc
+++ b/runtime/mem_map_test.cc
@@ -16,7 +16,7 @@
#include "mem_map.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "gtest/gtest.h"
namespace art {
diff --git a/runtime/mirror/object_test.cc b/runtime/mirror/object_test.cc
index 537fe85..e0fd6a2 100644
--- a/runtime/mirror/object_test.cc
+++ b/runtime/mirror/object_test.cc
@@ -36,7 +36,7 @@
#include "object_array-inl.h"
#include "handle_scope-inl.h"
#include "string-inl.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
namespace mirror {
diff --git a/runtime/os_linux.cc b/runtime/os_linux.cc
index 7ce17e0..d9a5813 100644
--- a/runtime/os_linux.cc
+++ b/runtime/os_linux.cc
@@ -23,7 +23,7 @@
#include "base/logging.h"
#include "base/unix_file/fd_file.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/runtime/parsed_options_test.cc b/runtime/parsed_options_test.cc
index 7f293cd..39f7638 100644
--- a/runtime/parsed_options_test.cc
+++ b/runtime/parsed_options_test.cc
@@ -16,7 +16,7 @@
#include "parsed_options.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "common_runtime_test.h"
namespace art {
diff --git a/runtime/profiler.h b/runtime/profiler.h
index 31fdc79..bcd7c29 100644
--- a/runtime/profiler.h
+++ b/runtime/profiler.h
@@ -29,7 +29,7 @@
#include "instrumentation.h"
#include "os.h"
#include "safe_map.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 78a93fd..d183cba 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -72,7 +72,7 @@
#include "trace.h"
#include "transaction.h"
#include "profiler.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "verifier/method_verifier.h"
#include "well_known_classes.h"
diff --git a/runtime/thread.h b/runtime/thread.h
index 83f7b8e..be7634f 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -39,7 +39,7 @@
#include "stack.h"
#include "thread_state.h"
#include "throw_location.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/runtime/trace.h b/runtime/trace.h
index bf4995a..ef6c642 100644
--- a/runtime/trace.h
+++ b/runtime/trace.h
@@ -27,7 +27,7 @@
#include "instrumentation.h"
#include "os.h"
#include "safe_map.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/runtime/utils.cc b/runtime/utils.cc
index c332bdf..f26b598 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -25,7 +25,7 @@
#include <unistd.h>
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "base/stl_util.h"
#include "base/unix_file/fd_file.h"
#include "dex_file-inl.h"
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index cea2403..14200f7 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -33,7 +33,7 @@
#include "reg_type_cache-inl.h"
#include "register_line.h"
#include "safe_map.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/runtime/verifier/method_verifier_test.cc b/runtime/verifier/method_verifier_test.cc
index 9dca7f5..2bcf3e0 100644
--- a/runtime/verifier/method_verifier_test.cc
+++ b/runtime/verifier/method_verifier_test.cc
@@ -18,7 +18,7 @@
#include <stdio.h>
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "class_linker.h"
#include "common_runtime_test.h"
#include "dex_file.h"
diff --git a/runtime/verifier/register_line.h b/runtime/verifier/register_line.h
index 8b2dadb..f9f3e31 100644
--- a/runtime/verifier/register_line.h
+++ b/runtime/verifier/register_line.h
@@ -22,7 +22,7 @@
#include "dex_instruction.h"
#include "reg_type.h"
#include "safe_map.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
namespace verifier {
diff --git a/runtime/zip_archive.cc b/runtime/zip_archive.cc
index ddac7d4..13b4219 100644
--- a/runtime/zip_archive.cc
+++ b/runtime/zip_archive.cc
@@ -26,7 +26,7 @@
#include "base/stringprintf.h"
#include "base/unix_file/fd_file.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/runtime/zip_archive.h b/runtime/zip_archive.h
index 3ef0e6b..edaa88b 100644
--- a/runtime/zip_archive.h
+++ b/runtime/zip_archive.h
@@ -27,7 +27,7 @@
#include "mem_map.h"
#include "os.h"
#include "safe_map.h"
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
namespace art {
diff --git a/runtime/zip_archive_test.cc b/runtime/zip_archive_test.cc
index c43fee5..d0624cf 100644
--- a/runtime/zip_archive_test.cc
+++ b/runtime/zip_archive_test.cc
@@ -21,7 +21,7 @@
#include <sys/types.h>
#include <zlib.h>
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "common_runtime_test.h"
#include "os.h"
diff --git a/test/ReferenceMap/stack_walk_refmap_jni.cc b/test/ReferenceMap/stack_walk_refmap_jni.cc
index 180db4c..d8a0eef 100644
--- a/test/ReferenceMap/stack_walk_refmap_jni.cc
+++ b/test/ReferenceMap/stack_walk_refmap_jni.cc
@@ -16,7 +16,7 @@
#include <stdio.h>
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "class_linker.h"
#include "dex_file-inl.h"
#include "gc_map.h"
diff --git a/test/StackWalk/stack_walk_jni.cc b/test/StackWalk/stack_walk_jni.cc
index 528586e..d230ddd 100644
--- a/test/StackWalk/stack_walk_jni.cc
+++ b/test/StackWalk/stack_walk_jni.cc
@@ -16,7 +16,7 @@
#include <stdio.h>
-#include "UniquePtr.h"
+#include "UniquePtrCompat.h"
#include "class_linker.h"
#include "gc_map.h"
#include "mirror/art_method.h"