LSE fix removing observable stores with throwing instuctions
Throwing instructions can make some stores observable that
wouldn't be observable othwerwise.
Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Bug: 229706824, 227283233
Change-Id: I03683184db0a2b8c42623fc1148efbec8f5cae11
(cherry picked from commit ea24a14ff37c708360b4cb38baba82af0931d451)
Merged-In: I03683184db0a2b8c42623fc1148efbec8f5cae11
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 827a29f..35cb2a3 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -776,9 +776,6 @@
"name": "art-run-test-530-checker-lse-simd[com.google.android.art.apex]"
},
{
- "name": "art-run-test-530-checker-lse2[com.google.android.art.apex]"
- },
- {
"name": "art-run-test-530-instanceof-checkcast[com.google.android.art.apex]"
},
{
@@ -2071,9 +2068,6 @@
"name": "art-run-test-530-checker-lse-simd"
},
{
- "name": "art-run-test-530-checker-lse2"
- },
- {
"name": "art-run-test-530-instanceof-checkcast"
},
{
diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc
index 4651210..e3d8481 100644
--- a/compiler/optimizing/load_store_elimination.cc
+++ b/compiler/optimizing/load_store_elimination.cc
@@ -615,6 +615,11 @@
return PhiPlaceholderIndex(phi_placeholder.GetPhiPlaceholder());
}
+ bool IsEscapingObject(ReferenceInfo* info, HBasicBlock* block, size_t index) {
+ return !info->IsSingletonAndRemovable() &&
+ !(info->IsPartialSingleton() && IsPartialNoEscape(block, index));
+ }
+
bool IsPartialNoEscape(HBasicBlock* blk, size_t idx) {
auto* ri = heap_location_collector_.GetHeapLocation(idx)->GetReferenceInfo();
if (!ri->IsPartialSingleton()) {
@@ -1035,8 +1040,8 @@
}
void VisitDeoptimize(HDeoptimize* instruction) override {
- ScopedArenaVector<ValueRecord>& heap_values =
- heap_values_for_[instruction->GetBlock()->GetBlockId()];
+ HBasicBlock* block = instruction->GetBlock();
+ ScopedArenaVector<ValueRecord>& heap_values = heap_values_for_[block->GetBlockId()];
for (size_t i = 0u, size = heap_values.size(); i != size; ++i) {
Value* stored_by = &heap_values[i].stored_by;
if (stored_by->IsUnknown()) {
@@ -1049,7 +1054,9 @@
if (info->IsSingleton()) {
HInstruction* reference = info->GetReference();
// Finalizable objects always escape.
- if (!reference->IsNewInstance() || !reference->AsNewInstance()->IsFinalizable()) {
+ const bool finalizable_object =
+ reference->IsNewInstance() && reference->AsNewInstance()->IsFinalizable();
+ if (!finalizable_object && !IsEscapingObject(info, block, i)) {
// Check whether the reference for a store is used by an environment local of
// the HDeoptimize. If not, the singleton is not observed after deoptimization.
const HUseList<HEnvironment*>& env_uses = reference->GetEnvUses();
@@ -1073,8 +1080,7 @@
ScopedArenaVector<ValueRecord>& heap_values = heap_values_for_[block->GetBlockId()];
for (size_t i = 0u, size = heap_values.size(); i != size; ++i) {
ReferenceInfo* ref_info = heap_location_collector_.GetHeapLocation(i)->GetReferenceInfo();
- if (!ref_info->IsSingletonAndRemovable() &&
- !(ref_info->IsPartialSingleton() && IsPartialNoEscape(block, i))) {
+ if (IsEscapingObject(ref_info, block, i)) {
KeepStores(heap_values[i].stored_by);
heap_values[i].stored_by = Value::PureUnknown();
}
@@ -1089,11 +1095,64 @@
HandleExit(return_void->GetBlock());
}
+ void HandleThrowingInstruction(HInstruction* instruction) {
+ DCHECK(instruction->CanThrow());
+ HandleExit(instruction->GetBlock());
+ }
+
+ void VisitMethodEntryHook(HMethodEntryHook* method_entry) override {
+ HandleThrowingInstruction(method_entry);
+ }
+
+ void VisitMethodExitHook(HMethodExitHook* method_exit) override {
+ HandleThrowingInstruction(method_exit);
+ }
+
+ void VisitDivZeroCheck(HDivZeroCheck* div_zero_check) override {
+ HandleThrowingInstruction(div_zero_check);
+ }
+
+ void VisitNullCheck(HNullCheck* null_check) override {
+ HandleThrowingInstruction(null_check);
+ }
+
+ void VisitBoundsCheck(HBoundsCheck* bounds_check) override {
+ HandleThrowingInstruction(bounds_check);
+ }
+
+ void VisitLoadClass(HLoadClass* load_class) override {
+ if (load_class->CanThrow()) {
+ HandleThrowingInstruction(load_class);
+ }
+ }
+
+ void VisitLoadString(HLoadString* load_string) override {
+ if (load_string->CanThrow()) {
+ HandleThrowingInstruction(load_string);
+ }
+ }
+
+ void VisitStringBuilderAppend(HStringBuilderAppend* sb_append) override {
+ HandleThrowingInstruction(sb_append);
+ }
+
void VisitThrow(HThrow* throw_instruction) override {
- HandleExit(throw_instruction->GetBlock());
+ HandleThrowingInstruction(throw_instruction);
+ }
+
+ void VisitCheckCast(HCheckCast* check_cast) override {
+ HandleThrowingInstruction(check_cast);
+ }
+
+ void VisitMonitorOperation(HMonitorOperation* monitor_op) override {
+ if (monitor_op->CanThrow()) {
+ HandleThrowingInstruction(monitor_op);
+ }
}
void HandleInvoke(HInstruction* instruction) {
+ // If `instruction` can throw we have to presume all stores are visible.
+ const bool can_throw = instruction->CanThrow();
SideEffects side_effects = instruction->GetSideEffects();
ScopedArenaVector<ValueRecord>& heap_values =
heap_values_for_[instruction->GetBlock()->GetBlockId()];
@@ -1124,7 +1183,7 @@
(ref_info->IsPartialSingleton() && partial_singleton_did_not_escape(ref_info, blk))) {
// Singleton references cannot be seen by the callee.
} else {
- if (side_effects.DoesAnyRead() || side_effects.DoesAnyWrite()) {
+ if (can_throw || side_effects.DoesAnyRead() || side_effects.DoesAnyWrite()) {
// Previous stores may become visible (read) and/or impossible for LSE to track (write).
KeepStores(heap_values[i].stored_by);
heap_values[i].stored_by = Value::PureUnknown();
@@ -1177,11 +1236,11 @@
// new_instance can potentially be eliminated.
singleton_new_instances_.push_back(new_instance);
}
- ScopedArenaVector<ValueRecord>& heap_values =
- heap_values_for_[new_instance->GetBlock()->GetBlockId()];
+ HBasicBlock* block = new_instance->GetBlock();
+ ScopedArenaVector<ValueRecord>& heap_values = heap_values_for_[block->GetBlockId()];
for (size_t i = 0u, size = heap_values.size(); i != size; ++i) {
- HInstruction* ref =
- heap_location_collector_.GetHeapLocation(i)->GetReferenceInfo()->GetReference();
+ ReferenceInfo* info = heap_location_collector_.GetHeapLocation(i)->GetReferenceInfo();
+ HInstruction* ref = info->GetReference();
size_t offset = heap_location_collector_.GetHeapLocation(i)->GetOffset();
if (ref == new_instance) {
if (offset >= mirror::kObjectHeaderSize ||
@@ -1195,6 +1254,10 @@
heap_values[i].value = Value::ForInstruction(new_instance->GetLoadClass());
heap_values[i].stored_by = Value::PureUnknown();
}
+ } else if (IsEscapingObject(info, block, i)) {
+ // Since NewInstance can throw, we presume all previous stores could be visible.
+ KeepStores(heap_values[i].stored_by);
+ heap_values[i].stored_by = Value::PureUnknown();
}
}
}
@@ -1214,19 +1277,29 @@
// new_array may throw NegativeArraySizeException. Keep it.
}
}
- ScopedArenaVector<ValueRecord>& heap_values =
- heap_values_for_[new_array->GetBlock()->GetBlockId()];
+ HBasicBlock* block = new_array->GetBlock();
+ ScopedArenaVector<ValueRecord>& heap_values = heap_values_for_[block->GetBlockId()];
for (size_t i = 0u, size = heap_values.size(); i != size; ++i) {
HeapLocation* location = heap_location_collector_.GetHeapLocation(i);
- HInstruction* ref = location->GetReferenceInfo()->GetReference();
+ ReferenceInfo* info = location->GetReferenceInfo();
+ HInstruction* ref = info->GetReference();
if (ref == new_array && location->GetIndex() != nullptr) {
// Array elements are set to default heap values.
heap_values[i].value = Value::Default();
heap_values[i].stored_by = Value::PureUnknown();
+ } else if (IsEscapingObject(info, block, i)) {
+ // Since NewArray can throw, we presume all previous stores could be visible.
+ KeepStores(heap_values[i].stored_by);
+ heap_values[i].stored_by = Value::PureUnknown();
}
}
}
+ void VisitInstruction(HInstruction* instruction) override {
+ // Throwing instructions must be handled specially.
+ DCHECK(!instruction->CanThrow());
+ }
+
bool ShouldPerformPartialLSE() const {
return perform_partial_lse_ && !GetGraph()->IsCompilingOsr();
}
@@ -1829,7 +1902,7 @@
if (instruction->CanThrow()) {
// Previous stores can become visible.
- HandleExit(instruction->GetBlock());
+ HandleThrowingInstruction(instruction);
// We cannot remove a possibly throwing store.
// After marking it as kept, it does not matter if we track it in `stored_by` or not.
kept_stores_.SetBit(instruction->GetId());
diff --git a/test/530-checker-lse/src/Main.java b/test/530-checker-lse/src/Main.java
index e97bd36..5d55d3e 100644
--- a/test/530-checker-lse/src/Main.java
+++ b/test/530-checker-lse/src/Main.java
@@ -1021,13 +1021,18 @@
/// CHECK-START: int Main.test33(TestClass, boolean) load_store_elimination (after)
/// CHECK-DAG: InstanceFieldSet
- /// CHECK-DAG: Phi
+ /// CHECK-DAG: InstanceFieldSet
+ /// CHECK-DAG: <<Phi:i\d+>> Phi
/// CHECK-START: int Main.test33(TestClass, boolean) load_store_elimination (after)
/// CHECK: InstanceFieldSet
+ /// CHECK: InstanceFieldSet
/// CHECK-NOT: InstanceFieldSet
- // Test eliminating non-observable stores.
+ // Test that we are not eliminating the if/else sets to `obj.i`. We have `NullCheck`s on `obj`
+ // when doing `obj.i`. Since `NullCheck` can throw, we save the stores.
+ // The 3rd `obj.i` set is redundant and can be eliminated. It will have the same value and it is
+ // not needed.
static int test33(TestClass obj, boolean x) {
int phi;
if (x) {
@@ -1217,6 +1222,48 @@
return obj.next.i;
}
+ private static int test40() {
+ int[] array = new int[1];
+ try {
+ $noinline$fillArrayTest40(array, 100, 0);
+ System.out.println("UNREACHABLE");
+ } catch (Throwable expected) {
+ }
+ assertIntEquals(array[0], 1);
+ try {
+ $noinline$fillArrayTest40(array, 100, 1);
+ System.out.println("UNREACHABLE");
+ } catch (Throwable expected) {
+ }
+ assertIntEquals(array[0], 2);
+ $noinline$fillArrayTest40(array, 100, 2);
+ assertIntEquals(array[0], 150);
+ return array[0];
+ }
+
+ /// CHECK-START: void Main.$noinline$fillArrayTest40(int[], int, int) load_store_elimination (before)
+ /// CHECK: ArraySet
+ /// CHECK: DivZeroCheck
+ /// CHECK: ArraySet
+ /// CHECK: DivZeroCheck
+ /// CHECK: ArraySet
+
+ /// CHECK-START: void Main.$noinline$fillArrayTest40(int[], int, int) load_store_elimination (after)
+ /// CHECK: ArraySet
+ /// CHECK: DivZeroCheck
+ /// CHECK: ArraySet
+ /// CHECK: DivZeroCheck
+ /// CHECK: ArraySet
+
+ // Check that the stores to array[0] are not eliminated since we can throw in between the stores.
+ private static void $noinline$fillArrayTest40(int[] array, int a, int b) {
+ array[0] = 1;
+ int x = a / b;
+ array[0] = 2;
+ int y = a / (b - 1);
+ array[0] = x + y;
+ }
+
/// CHECK-START: int Main.$noinline$testConversion1(TestClass, int) load_store_elimination (before)
/// CHECK-DAG: InstanceFieldSet
/// CHECK-DAG: InstanceFieldSet
@@ -1655,12 +1702,13 @@
/// CHECK: InstanceFieldSet
/// CHECK-START: int Main.testStoreStore6(TestClass2, TestClass2) load_store_elimination (after)
- /// CHECK-NOT: InstanceFieldSet
+ /// CHECK: InstanceFieldSet
/// CHECK: InstanceFieldGet
/// CHECK: InstanceFieldSet
private static int testStoreStore6(TestClass2 obj1, TestClass2 obj2) {
- obj1.i = 81; // This store is not needed since obj2.j cannot load from it.
+ obj1.i = 81; // Even though the value in `obj1.i` will be overridden below, this store is needed
+ // since obj2.j has a NullCheck and can throw.
int j = obj2.j;
obj1.i = 82;
return j;
@@ -4116,6 +4164,7 @@
assertIntEquals(test38(new TestClass(), false), 2);
assertIntEquals(test39(new TestClass(), true), 0);
assertIntEquals(test39(new TestClass(), false), 1);
+ assertIntEquals(test40(), 150);
testFinalizableByForcingGc();
testFinalizableWithLoopByForcingGc();
diff --git a/test/530-checker-lse2/Android.bp b/test/530-checker-lse2/Android.bp
deleted file mode 100644
index ca5e7f0..0000000
--- a/test/530-checker-lse2/Android.bp
+++ /dev/null
@@ -1,43 +0,0 @@
-// Generated by `regen-test-files`. Do not edit manually.
-
-// Build rules for ART run-test `530-checker-lse2`.
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "art_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["art_license"],
-}
-
-// Test's Dex code.
-java_test {
- name: "art-run-test-530-checker-lse2",
- defaults: ["art-run-test-defaults"],
- test_config_template: ":art-run-test-target-template",
- srcs: ["src/**/*.java"],
- data: [
- ":art-run-test-530-checker-lse2-expected-stdout",
- ":art-run-test-530-checker-lse2-expected-stderr",
- ],
- // Include the Java source files in the test's artifacts, to make Checker assertions
- // available to the TradeFed test runner.
- include_srcs: true,
-}
-
-// Test's expected standard output.
-genrule {
- name: "art-run-test-530-checker-lse2-expected-stdout",
- out: ["art-run-test-530-checker-lse2-expected-stdout.txt"],
- srcs: ["expected-stdout.txt"],
- cmd: "cp -f $(in) $(out)",
-}
-
-// Test's expected standard error.
-genrule {
- name: "art-run-test-530-checker-lse2-expected-stderr",
- out: ["art-run-test-530-checker-lse2-expected-stderr.txt"],
- srcs: ["expected-stderr.txt"],
- cmd: "cp -f $(in) $(out)",
-}
diff --git a/test/530-checker-lse2/expected-stderr.txt b/test/530-checker-lse2/expected-stderr.txt
deleted file mode 100644
index e69de29..0000000
--- a/test/530-checker-lse2/expected-stderr.txt
+++ /dev/null
diff --git a/test/530-checker-lse2/expected-stdout.txt b/test/530-checker-lse2/expected-stdout.txt
deleted file mode 100644
index e18fc7e..0000000
--- a/test/530-checker-lse2/expected-stdout.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Start....
-r = 9.649776E8
-mZ = false
-mI = 0
-mJ = -576460752303423488
-mF = NaN
-mD = NaN
-Done....
diff --git a/test/530-checker-lse2/info.txt b/test/530-checker-lse2/info.txt
deleted file mode 100644
index 8dd3f50..0000000
--- a/test/530-checker-lse2/info.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Checker test for testing store/allocation elimination in presence of
-HDeoptimize.
diff --git a/test/530-checker-lse2/src/Main.java b/test/530-checker-lse2/src/Main.java
deleted file mode 100644
index 491a9a1..0000000
--- a/test/530-checker-lse2/src/Main.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-import java.util.Arrays;
-
-// Modified from a fuzz test.
-public class Main {
-
- private interface X {
- int x();
- }
-
- private class A {
- public int a() {
- return (+ (Math.multiplyExact(mI, mI)));
- }
- }
-
- private class B extends A implements X {
- public int a() {
- return super.a() + ((int) (Math.max(364746077.0f, ((float) mD))));
- }
- public int x() {
- return (mI >> (mI++));
- }
- }
-
- private static class C implements X {
- public static int s() {
- return 671468641;
- }
- public int c() {
- return -383762838;
- }
- public int x() {
- return -138813312;
- }
- }
-
- private A mA = new B();
- private B mB = new B();
- private X mBX = new B();
- private C mC = new C();
- private X mCX = new C();
-
- private boolean mZ = false;
- private int mI = 0;
- private long mJ = 0;
- private float mF = 0;
- private double mD = 0;
-
- private boolean[] mArray = new boolean[576];
-
- private Main() {
- boolean a = false;
- for (int i0 = 0; i0 < 576; i0++) {
- mArray[i0] = a;
- a = !a;
- }
- }
-
- /// CHECK-START: float Main.testMethod() load_store_elimination (before)
- /// CHECK-DAG: Deoptimize
- /// CHECK-DAG: Deoptimize
- /// CHECK-DAG: NewInstance
- /// CHECK-DAG: ConstructorFence
- /// CHECK-DAG: NewInstance
- /// CHECK-DAG: ConstructorFence
- /// CHECK-DAG: NewInstance
- /// CHECK-DAG: ConstructorFence
- /// CHECK-DAG: NewInstance
- /// CHECK-DAG: ConstructorFence
- /// CHECK-DAG: NewInstance
- /// CHECK-DAG: ConstructorFence
- /// CHECK-DAG: NewInstance
- /// CHECK-DAG: ConstructorFence
- /// CHECK-DAG: NewInstance
- /// CHECK-DAG: ConstructorFence
- /// CHECK-DAG: NewInstance
- /// CHECK-DAG: ConstructorFence
- /// CHECK-DAG: NewInstance
- /// CHECK-DAG: ConstructorFence
- /// CHECK-DAG: NewInstance
- /// CHECK-DAG: ConstructorFence
- /// CHECK-DAG: NewInstance
- /// CHECK-DAG: ConstructorFence
- /// CHECK-DAG: NewInstance
- /// CHECK-DAG: NewInstance
- /// CHECK-DAG: NewInstance
- /// CHECK-NOT: NewInstance
-
- /// CHECK-START: float Main.testMethod() load_store_elimination (after)
- /// CHECK-DAG: Deoptimize
- /// CHECK-DAG: Deoptimize
- /// CHECK-NOT: NewInstance
- /// CHECK-NOT: ConstructorFence
-
- private float testMethod() {
- {
- // Each of the "new" statements here will initialize an object with final fields,
- // which after inlining will also retain a constructor fence.
- //
- // After LSE we remove the 'new-instance' and the associated constructor fence.
- int lI0 = (-1456058746 << mI);
- mD = ((double)(int)(double) mD);
- for (int i0 = 56 - 1; i0 >= 0; i0--) {
- mArray[i0] &= (Boolean.logicalOr(((true ? ((boolean) new Boolean((mZ))) : mZ) || mArray[i0]), (mZ)));
- mF *= (mF * mF);
- if ((mZ ^ true)) {
- mF *= ((float)(int)(float) 267827331.0f);
- mZ ^= ((false & ((boolean) new Boolean(false))) | mZ);
- for (int i1 = 576 - 1; i1 >= 0; i1--) {
- mZ &= ((mArray[279]) | ((boolean) new Boolean(true)));
- mD -= (--mD);
- for (int i2 = 56 - 1; i2 >= 0; i2--) {
- mF /= (mF - mF);
- mI = (Math.min(((int) new Integer(mI)), (766538816 * (++mI))));
- mF += (mZ ? (mB.a()) : ((! mZ) ? -752042357.0f : (++mF)));
- mJ |= ((long) new Long((-2084191070L + (mJ | mJ))));
- lI0 |= ((int) new Integer(((int) new Integer(mI))));
- if (((boolean) new Boolean(false))) {
- mZ &= (mZ);
- mF *= (mF--);
- mD = (Double.POSITIVE_INFINITY);
- mF += ((float)(int)(float) (-2026938813.0f * 638401585.0f));
- mJ = (--mJ);
- for (int i3 = 56 - 1; i3 >= 0; i3--) {
- mI &= (- mI);
- mD = (--mD);
- mArray[426] = (mZ || false);
- mF -= (((this instanceof Main) ? mF : mF) + 976981405.0f);
- mZ &= ((mZ) & (this instanceof Main));
- }
- mZ ^= (Float.isFinite(-1975953895.0f));
- } else {
- mJ /= ((long) (Math.nextDown(-1519600008.0f)));
- mJ <<= (Math.round(1237681786.0));
- }
- }
- mArray[i0] &= (false || ((1256071300.0f != -353296391.0f) ? false : (mZ ^ mArray[i0])));
- mF *= (+ ((float) mD));
- for (int i2 = 0; i2 < 576; i2++) {
- mD *= ((double) lI0);
- lI0 = (lI0 & (Integer.MIN_VALUE));
- mF -= (--mF);
- }
- if ((this instanceof Main)) {
- mZ ^= ((boolean) new Boolean(true));
- } else {
- {
- int lI1 = (mZ ? (--lI0) : 1099574344);
- mJ >>= (Math.incrementExact(mJ));
- mJ = (~ -2103354070L);
- }
- }
- }
- } else {
- mJ *= (- ((long) new Long(479832084L)));
- mJ %= (Long.MAX_VALUE);
- mD /= (--mD);
- if ((mI > ((mBX.x()) << mI))) {
- {
- long lJ0 = (mJ--);
- mI >>>= (mBX.x());
- }
- mF = (+ 505094603.0f);
- mD *= (((boolean) new Boolean((! false))) ? mD : 1808773781.0);
- mI *= (Integer.MIN_VALUE);
- for (int i1 = 576 - 1; i1 >= 0; i1--) {
- if (((boolean) new Boolean(false))) {
- mD += ((double)(float)(double) -1051436901.0);
- } else {
- mF -= ((float)(int)(float) (Float.min(mF, (mF--))));
- }
- for (int i2 = 0; i2 < 576; i2++) {
- mJ -= ((long) new Long(-1968644857L));
- mJ ^= (+ (mC.s()));
- }
- }
- } else {
- mF -= ((- mF) + -2145489966.0f);
- }
- mD -= (mD++);
- mD = (949112777.0 * 1209996119.0);
- }
- mZ &= (Boolean.logicalAnd(true, ((mZ) & (((boolean) new Boolean(true)) && true))));
- }
- }
- return ((float) 964977619L);
- }
-
- public static void main(String[] args) {
- System.out.println("Start....");
- Main t = new Main();
- float r = 1883600237.0f;
- try {
- r = t.testMethod();
- } catch (Exception e) {
- // Arithmetic, null pointer, index out of bounds, etc.
- System.out.println("An exception was caught.");
- }
- System.out.println("r = " + r);
- System.out.println("mZ = " + t.mZ);
- System.out.println("mI = " + t.mI);
- System.out.println("mJ = " + t.mJ);
- System.out.println("mF = " + t.mF);
- System.out.println("mD = " + t.mD);
- System.out.println("Done....");
- }
-}
-
diff --git a/test/etc/run-test-jar b/test/etc/run-test-jar
index 9a1bdad..75dc8fe 100755
--- a/test/etc/run-test-jar
+++ b/test/etc/run-test-jar
@@ -222,8 +222,7 @@
option="$1"
FLAGS="${FLAGS} $option"
if [ "x$option" = "x-Xmethod-trace" ]; then
- # Method tracing can slow some tests down a lot, in particular
- # 530-checker-lse2.
+ # Method tracing can slow some tests down a lot.
TIME_OUT_EXTRA=$((${TIME_OUT_EXTRA} + 1200))
fi
shift
diff --git a/test/knownfailures.json b/test/knownfailures.json
index c258f0f..3e485f6 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -375,7 +375,6 @@
},
{
"tests": ["530-checker-lse",
- "530-checker-lse2",
"030-bad-finalizer",
"080-oom-throw",
"1336-short-finalizer-timeout",
@@ -1259,7 +1258,7 @@
"description" : ["Gcstress requires the ability to open at least one file which means this test fails when it runs out."]
},
{
- "tests": ["530-checker-lse2", "141-class-unload", "071-dexfile"],
+ "tests": ["141-class-unload", "071-dexfile"],
"variant": "gcstress",
"bug": "b/111543628",
"description" : ["Test seems to timeout when run with gcstress due to slower unwinding by libbacktrace"]