Merge "Test fails on mips."
diff --git a/build/Android.common_build.mk b/build/Android.common_build.mk
index a443487..288bddd 100644
--- a/build/Android.common_build.mk
+++ b/build/Android.common_build.mk
@@ -295,10 +295,6 @@
art_cflags += -DIMT_SIZE=64
endif
-ifeq ($(ART_USE_OPTIMIZING_COMPILER),true)
- art_cflags += -DART_USE_OPTIMIZING_COMPILER=1
-endif
-
ifeq ($(ART_HEAP_POISONING),true)
art_cflags += -DART_HEAP_POISONING=1
art_asflags += -DART_HEAP_POISONING=1
diff --git a/build/Android.oat.mk b/build/Android.oat.mk
index 6e17ed3..d71ae29 100644
--- a/build/Android.oat.mk
+++ b/build/Android.oat.mk
@@ -52,18 +52,12 @@
core_pic_infix :=
core_dex2oat_dependency := $(DEX2OAT_DEPENDENCY)
- # With the optimizing compiler, we want to rerun dex2oat whenever there is
- # a dex2oat change to catch regressions early.
- ifeq ($(ART_USE_OPTIMIZING_COMPILER), true)
- core_dex2oat_dependency := $(DEX2OAT)
- endif
-
ifeq ($(1),default)
core_compile_options += --compiler-backend=Quick
endif
ifeq ($(1),optimizing)
core_compile_options += --compiler-backend=Optimizing
- core_dex2oat_dependency := $(DEX2OAT)
+ core_dex2oat_dependency += $(DEX2OAT)
core_infix := -optimizing
endif
ifeq ($(1),interpreter)
@@ -178,18 +172,12 @@
core_pic_infix :=
core_dex2oat_dependency := $(DEX2OAT_DEPENDENCY)
- # With the optimizing compiler, we want to rerun dex2oat whenever there is
- # a dex2oat change to catch regressions early.
- ifeq ($(ART_USE_OPTIMIZING_COMPILER), true)
- core_dex2oat_dependency := $(DEX2OAT)
- endif
-
ifeq ($(1),default)
core_compile_options += --compiler-backend=Quick
endif
ifeq ($(1),optimizing)
core_compile_options += --compiler-backend=Optimizing
- core_dex2oat_dependency := $(DEX2OAT)
+ core_dex2oat_dependency += $(DEX2OAT)
core_infix := -optimizing
endif
ifeq ($(1),interpreter)
diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h
index dc2bc5c..67b4428 100644
--- a/compiler/common_compiler_test.h
+++ b/compiler/common_compiler_test.h
@@ -92,7 +92,7 @@
void UnreserveImageSpace();
- Compiler::Kind compiler_kind_ = kUseOptimizingCompiler ? Compiler::kOptimizing : Compiler::kQuick;
+ Compiler::Kind compiler_kind_ = Compiler::kOptimizing;
std::unique_ptr<CompilerOptions> compiler_options_;
std::unique_ptr<VerificationResults> verification_results_;
std::unique_ptr<DexFileToMethodInlinerMap> method_inliner_map_;
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 039029a..94437ca 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -247,12 +247,14 @@
return false;
}
- uint16_t class_def_idx = resolved_method->GetDeclaringClass()->GetDexClassDefIndex();
- if (!compiler_driver_->IsMethodVerifiedWithoutFailures(
- resolved_method->GetDexMethodIndex(), class_def_idx, *resolved_method->GetDexFile())) {
- VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file)
- << " couldn't be verified, so it cannot be inlined";
- return false;
+ if (!resolved_method->GetDeclaringClass()->IsVerified()) {
+ uint16_t class_def_idx = resolved_method->GetDeclaringClass()->GetDexClassDefIndex();
+ if (!compiler_driver_->IsMethodVerifiedWithoutFailures(
+ resolved_method->GetDexMethodIndex(), class_def_idx, *resolved_method->GetDexFile())) {
+ VLOG(compiler) << "Method " << PrettyMethod(method_index, caller_dex_file)
+ << " couldn't be verified, so it cannot be inlined";
+ return false;
+ }
}
if (invoke_instruction->IsInvokeStaticOrDirect() &&
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index cc32da1..680e2d7 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -235,11 +235,7 @@
UsageError(" --compiler-backend=(Quick|Optimizing): select compiler backend");
UsageError(" set.");
UsageError(" Example: --compiler-backend=Optimizing");
- if (kUseOptimizingCompiler) {
- UsageError(" Default: Optimizing");
- } else {
- UsageError(" Default: Quick");
- }
+ UsageError(" Default: Optimizing");
UsageError("");
UsageError(" --compiler-filter="
"(verify-none"
@@ -503,7 +499,7 @@
class Dex2Oat FINAL {
public:
explicit Dex2Oat(TimingLogger* timings) :
- compiler_kind_(kUseOptimizingCompiler ? Compiler::kOptimizing : Compiler::kQuick),
+ compiler_kind_(Compiler::kOptimizing),
instruction_set_(kRuntimeISA),
// Take the default set of instruction features from the build.
verification_results_(nullptr),
@@ -752,10 +748,9 @@
void ProcessOptions(ParserOptions* parser_options) {
image_ = (!image_filename_.empty());
- if (!parser_options->requested_specific_compiler && !kUseOptimizingCompiler) {
- // If no specific compiler is requested, the current behavior is
- // to compile the boot image with Quick, and the rest with Optimizing.
- compiler_kind_ = image_ ? Compiler::kQuick : Compiler::kOptimizing;
+ if (image_) {
+ // We need the boot image to always be debuggable.
+ parser_options->debuggable = true;
}
if (oat_filename_.empty() && oat_fd_ == -1) {
diff --git a/runtime/globals.h b/runtime/globals.h
index d70f3ab..987a94e 100644
--- a/runtime/globals.h
+++ b/runtime/globals.h
@@ -58,12 +58,6 @@
static constexpr bool kIsTargetBuild = false;
#endif
-#if defined(ART_USE_OPTIMIZING_COMPILER)
-static constexpr bool kUseOptimizingCompiler = true;
-#else
-static constexpr bool kUseOptimizingCompiler = false;
-#endif
-
// Garbage collector constants.
static constexpr bool kMovingCollector = true;
static constexpr bool kMarkCompactSupport = false && kMovingCollector;
diff --git a/runtime/stack.cc b/runtime/stack.cc
index 7f72f8a..1d21a64 100644
--- a/runtime/stack.cc
+++ b/runtime/stack.cc
@@ -110,7 +110,7 @@
}
InlineInfo StackVisitor::GetCurrentInlineInfo() const {
- ArtMethod* outer_method = *GetCurrentQuickFrame();
+ ArtMethod* outer_method = GetOuterMethod();
uint32_t native_pc_offset = outer_method->NativeQuickPcOffset(cur_quick_frame_pc_);
CodeInfo code_info = outer_method->GetOptimizedCodeInfo();
StackMapEncoding encoding = code_info.ExtractEncoding();
@@ -194,11 +194,12 @@
}
bool StackVisitor::IsReferenceVReg(ArtMethod* m, uint16_t vreg) {
+ DCHECK_EQ(m, GetMethod());
// Process register map (which native and runtime methods don't have)
if (m->IsNative() || m->IsRuntimeMethod() || m->IsProxyMethod()) {
return false;
}
- if (m->IsOptimized(sizeof(void*))) {
+ if (GetOuterMethod()->IsOptimized(sizeof(void*))) {
return true; // TODO: Implement.
}
const uint8_t* native_gc_map = m->GetNativeGcMap(sizeof(void*));
@@ -251,7 +252,7 @@
if (GetVRegFromDebuggerShadowFrame(vreg, kind, val)) {
return true;
}
- if (m->IsOptimized(sizeof(void*))) {
+ if (GetOuterMethod()->IsOptimized(sizeof(void*))) {
return GetVRegFromOptimizedCode(m, vreg, kind, val);
} else {
return GetVRegFromQuickCode(m, vreg, kind, val);
@@ -288,15 +289,15 @@
bool StackVisitor::GetVRegFromOptimizedCode(ArtMethod* m, uint16_t vreg, VRegKind kind,
uint32_t* val) const {
+ ArtMethod* outer_method = GetOuterMethod();
+ const void* code_pointer = outer_method->GetQuickOatCodePointer(sizeof(void*));
+ DCHECK(code_pointer != nullptr);
DCHECK_EQ(m, GetMethod());
const DexFile::CodeItem* code_item = m->GetCodeItem();
DCHECK(code_item != nullptr) << PrettyMethod(m); // Can't be null or how would we compile
// its instructions?
uint16_t number_of_dex_registers = code_item->registers_size_;
DCHECK_LT(vreg, code_item->registers_size_);
- ArtMethod* outer_method = *GetCurrentQuickFrame();
- const void* code_pointer = outer_method->GetQuickOatCodePointer(sizeof(void*));
- DCHECK(code_pointer != nullptr);
CodeInfo code_info = outer_method->GetOptimizedCodeInfo();
StackMapEncoding encoding = code_info.ExtractEncoding();
@@ -405,7 +406,7 @@
if (cur_quick_frame_ != nullptr) {
DCHECK(context_ != nullptr); // You can't reliably read registers without a context.
DCHECK(m == GetMethod());
- if (m->IsOptimized(sizeof(void*))) {
+ if (GetOuterMethod()->IsOptimized(sizeof(void*))) {
return GetVRegPairFromOptimizedCode(m, vreg, kind_lo, kind_hi, val);
} else {
return GetVRegPairFromQuickCode(m, vreg, kind_lo, kind_hi, val);
@@ -481,7 +482,7 @@
if (cur_quick_frame_ != nullptr) {
DCHECK(context_ != nullptr); // You can't reliably write registers without a context.
DCHECK(m == GetMethod());
- if (m->IsOptimized(sizeof(void*))) {
+ if (GetOuterMethod()->IsOptimized(sizeof(void*))) {
return false;
} else {
return SetVRegFromQuickCode(m, vreg, new_value, kind);
@@ -590,7 +591,7 @@
if (cur_quick_frame_ != nullptr) {
DCHECK(context_ != nullptr); // You can't reliably write registers without a context.
DCHECK(m == GetMethod());
- if (m->IsOptimized(sizeof(void*))) {
+ if (GetOuterMethod()->IsOptimized(sizeof(void*))) {
return false;
} else {
return SetVRegPairFromQuickCode(m, vreg, new_value, kind_lo, kind_hi);
@@ -724,14 +725,14 @@
uintptr_t StackVisitor::GetReturnPc() const {
uint8_t* sp = reinterpret_cast<uint8_t*>(GetCurrentQuickFrame());
DCHECK(sp != nullptr);
- uint8_t* pc_addr = sp + GetMethod()->GetReturnPcOffset().SizeValue();
+ uint8_t* pc_addr = sp + GetOuterMethod()->GetReturnPcOffset().SizeValue();
return *reinterpret_cast<uintptr_t*>(pc_addr);
}
void StackVisitor::SetReturnPc(uintptr_t new_ret_pc) {
uint8_t* sp = reinterpret_cast<uint8_t*>(GetCurrentQuickFrame());
CHECK(sp != nullptr);
- uint8_t* pc_addr = sp + GetMethod()->GetReturnPcOffset().SizeValue();
+ uint8_t* pc_addr = sp + GetOuterMethod()->GetReturnPcOffset().SizeValue();
*reinterpret_cast<uintptr_t*>(pc_addr) = new_ret_pc;
}
diff --git a/runtime/stack.h b/runtime/stack.h
index 292c745..31acf0e 100644
--- a/runtime/stack.h
+++ b/runtime/stack.h
@@ -473,6 +473,10 @@
ArtMethod* GetMethod() const SHARED_REQUIRES(Locks::mutator_lock_);
+ ArtMethod* GetOuterMethod() const {
+ return *GetCurrentQuickFrame();
+ }
+
bool IsShadowFrame() const {
return cur_shadow_frame_ != nullptr;
}
diff --git a/test/535-deopt-and-inlining/expected.txt b/test/535-deopt-and-inlining/expected.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/535-deopt-and-inlining/expected.txt
diff --git a/test/535-deopt-and-inlining/info.txt b/test/535-deopt-and-inlining/info.txt
new file mode 100644
index 0000000..717612a
--- /dev/null
+++ b/test/535-deopt-and-inlining/info.txt
@@ -0,0 +1,2 @@
+Stress test for deoptimization and JIT, to ensure the
+stack visitor uses the right ArtMethod when deopting.
diff --git a/test/535-deopt-and-inlining/src/Main.java b/test/535-deopt-and-inlining/src/Main.java
new file mode 100644
index 0000000..c231bf0
--- /dev/null
+++ b/test/535-deopt-and-inlining/src/Main.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+
+ public static void run() {
+ // Loop enough to get JIT compilation.
+ for (int i = 0; i < 10000; ++i) {
+ doCall(new int[0]);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ run();
+ }
+
+ public static void doCall(int[] array) {
+ try {
+ deopt(array);
+ } catch (IndexOutOfBoundsException ioobe) {
+ // Expected
+ }
+ }
+
+ public static void deopt(int[] array) {
+ // Invoke `deopt` much more than `$inline$deopt` so that only `deopt` gets
+ // initially JITted.
+ if (call == 100) {
+ call = 0;
+ $inline$deopt(array);
+ } else {
+ call++;
+ }
+ }
+
+ public static void $inline$deopt(int[] array) {
+ array[0] = 1;
+ array[1] = 1;
+ }
+
+ static int call = 0;
+}
diff --git a/test/Android.run-test.mk b/test/Android.run-test.mk
index 49778cb..a103eac 100644
--- a/test/Android.run-test.mk
+++ b/test/Android.run-test.mk
@@ -490,14 +490,6 @@
$(IMAGE_TYPES),$(PICTEST_TYPES),$(DEBUGGABLE_TYPES),$(TEST_ART_BROKEN_OPTIMIZING_RUN_TESTS),$(ALL_ADDRESS_SIZES))
endif
-# If ART_USE_OPTIMIZING_COMPILER is set to true, then the default core.art has been
-# compiled with the optimizing compiler.
-ifeq ($(ART_USE_OPTIMIZING_COMPILER),true)
- ART_TEST_KNOWN_BROKEN += $(call all-run-test-names,$(TARGET_TYPES),$(RUN_TYPES),$(PREBUILD_TYPES), \
- default,$(RELOCATE_TYPES),$(TRACE_TYPES),$(GC_TYPES),$(JNI_TYPES), \
- $(IMAGE_TYPES),$(PICTEST_TYPES),$(DEBUGGABLE_TYPES),$(TEST_ART_BROKEN_OPTIMIZING_RUN_TESTS),$(ALL_ADDRESS_SIZES))
-endif
-
TEST_ART_BROKEN_OPTIMIZING_RUN_TESTS :=
# Tests that should fail when the optimizing compiler compiles them non-debuggable.