summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/optimizing/code_generator.cc21
-rw-r--r--compiler/optimizing/code_generator.h2
-rw-r--r--compiler/optimizing/code_generator_arm64.cc4
-rw-r--r--compiler/optimizing/code_generator_arm_vixl.cc4
-rw-r--r--compiler/optimizing/code_generator_riscv64.cc4
-rw-r--r--compiler/optimizing/code_generator_x86.cc4
-rw-r--r--compiler/optimizing/code_generator_x86_64.cc4
-rw-r--r--compiler/optimizing/dead_code_elimination.cc3
-rw-r--r--libartservice/service/java/com/android/server/art/PreRebootDexoptJob.java17
-rw-r--r--libartservice/service/java/com/android/server/art/prereboot/PreRebootDriver.java25
-rw-r--r--libartservice/service/java/com/android/server/art/prereboot/PreRebootStatsReporter.java7
-rw-r--r--libartservice/service/javatests/com/android/server/art/PreRebootDexoptJobTest.java25
-rw-r--r--libartservice/service/javatests/com/android/server/art/prereboot/PreRebootStatsReporterTest.java10
-rw-r--r--runtime/base/mutex.cc3
-rw-r--r--runtime/hidden_api.cc2
-rw-r--r--test/2038-hiddenapi-jvmti-ext/run.py5
-rw-r--r--test/2255-checker-branch-redirection/src/Main.java53
-rw-r--r--test/674-hiddenapi/run.py5
-rw-r--r--test/817-hiddenapi/run.py5
-rw-r--r--test/999-redefine-hiddenapi/run.py5
20 files changed, 117 insertions, 91 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc
index 79386defae..e84cfcbe80 100644
--- a/compiler/optimizing/code_generator.cc
+++ b/compiler/optimizing/code_generator.cc
@@ -690,7 +690,6 @@ void CodeGenerator::GenerateUnresolvedFieldAccess(
HInstruction* field_access,
DataType::Type field_type,
uint32_t field_index,
- [[maybe_unused]] uint32_t dex_pc,
const FieldAccessCallingConvention& calling_convention) {
LocationSummary* locations = field_access->GetLocations();
@@ -1168,26 +1167,6 @@ void CodeGenerator::RecordPcInfo(HInstruction* instruction,
// the regular case, we retrieve the dex_pc from the instruction's environment.
DCHECK_IMPLIES(native_debug_info, GetCompilerOptions().GetNativeDebuggable());
DCHECK_IMPLIES(!native_debug_info, instruction->HasEnvironment()) << *instruction;
- // The code generated for some type conversions
- // may call the runtime, thus normally requiring a subsequent
- // call to this method. However, the method verifier does not
- // produce PC information for certain instructions, which are
- // considered "atomic" (they cannot join a GC).
- // Therefore we do not currently record PC information for such
- // instructions. As this may change later, we added this special
- // case so that code generators may nevertheless call
- // CodeGenerator::RecordPcInfo without triggering an error in
- // CodeGenerator::BuildNativeGCMap ("Missing ref for dex pc 0x")
- // thereafter.
- if (instruction->IsTypeConversion()) {
- return;
- }
- if (instruction->IsRem()) {
- DataType::Type type = instruction->AsRem()->GetResultType();
- if ((type == DataType::Type::kFloat32) || (type == DataType::Type::kFloat64)) {
- return;
- }
- }
LocationSummary* locations = instruction->GetLocations();
uint32_t register_mask = locations->GetRegisterMask();
diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h
index 741d3fb589..3919bb0cc1 100644
--- a/compiler/optimizing/code_generator.h
+++ b/compiler/optimizing/code_generator.h
@@ -641,12 +641,10 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> {
DataType::Type field_type,
const FieldAccessCallingConvention& calling_convention);
-// TODO(solanes): Remove dex_pc from this method
void GenerateUnresolvedFieldAccess(
HInstruction* field_access,
DataType::Type field_type,
uint32_t field_index,
- [[maybe_unused]] uint32_t dex_pc,
const FieldAccessCallingConvention& calling_convention);
static void CreateLoadClassRuntimeCallLocationSummary(HLoadClass* cls,
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index b6fe630f64..58447919f6 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -6656,7 +6656,6 @@ void InstructionCodeGeneratorARM64::VisitUnresolvedInstanceFieldGet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
@@ -6673,7 +6672,6 @@ void InstructionCodeGeneratorARM64::VisitUnresolvedInstanceFieldSet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
@@ -6690,7 +6688,6 @@ void InstructionCodeGeneratorARM64::VisitUnresolvedStaticFieldGet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
@@ -6707,7 +6704,6 @@ void InstructionCodeGeneratorARM64::VisitUnresolvedStaticFieldSet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc
index 20e9d4e0ff..a7854ac886 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -6445,7 +6445,6 @@ void InstructionCodeGeneratorARMVIXL::VisitUnresolvedInstanceFieldGet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
@@ -6462,7 +6461,6 @@ void InstructionCodeGeneratorARMVIXL::VisitUnresolvedInstanceFieldSet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
@@ -6479,7 +6477,6 @@ void InstructionCodeGeneratorARMVIXL::VisitUnresolvedStaticFieldGet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
@@ -6496,7 +6493,6 @@ void InstructionCodeGeneratorARMVIXL::VisitUnresolvedStaticFieldSet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
diff --git a/compiler/optimizing/code_generator_riscv64.cc b/compiler/optimizing/code_generator_riscv64.cc
index cd34b90f98..ba2e307af5 100644
--- a/compiler/optimizing/code_generator_riscv64.cc
+++ b/compiler/optimizing/code_generator_riscv64.cc
@@ -5085,7 +5085,6 @@ void InstructionCodeGeneratorRISCV64::VisitUnresolvedInstanceFieldGet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
@@ -5102,7 +5101,6 @@ void InstructionCodeGeneratorRISCV64::VisitUnresolvedInstanceFieldSet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
@@ -5119,7 +5117,6 @@ void InstructionCodeGeneratorRISCV64::VisitUnresolvedStaticFieldGet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
@@ -5136,7 +5133,6 @@ void InstructionCodeGeneratorRISCV64::VisitUnresolvedStaticFieldSet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 58d38feb8d..ae31e9f198 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -6397,7 +6397,6 @@ void InstructionCodeGeneratorX86::VisitUnresolvedInstanceFieldGet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
@@ -6414,7 +6413,6 @@ void InstructionCodeGeneratorX86::VisitUnresolvedInstanceFieldSet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
@@ -6431,7 +6429,6 @@ void InstructionCodeGeneratorX86::VisitUnresolvedStaticFieldGet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
@@ -6448,7 +6445,6 @@ void InstructionCodeGeneratorX86::VisitUnresolvedStaticFieldSet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index 9133f87c7b..891bdd72e8 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -5709,7 +5709,6 @@ void InstructionCodeGeneratorX86_64::VisitUnresolvedInstanceFieldGet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
@@ -5726,7 +5725,6 @@ void InstructionCodeGeneratorX86_64::VisitUnresolvedInstanceFieldSet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
@@ -5743,7 +5741,6 @@ void InstructionCodeGeneratorX86_64::VisitUnresolvedStaticFieldGet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
@@ -5760,7 +5757,6 @@ void InstructionCodeGeneratorX86_64::VisitUnresolvedStaticFieldSet(
codegen_->GenerateUnresolvedFieldAccess(instruction,
instruction->GetFieldType(),
instruction->GetFieldIndex(),
- instruction->GetDexPc(),
calling_convention);
}
diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc
index c5ec0b93b2..b8cd39e77f 100644
--- a/compiler/optimizing/dead_code_elimination.cc
+++ b/compiler/optimizing/dead_code_elimination.cc
@@ -488,7 +488,8 @@ void HDeadCodeElimination::MaybeAddPhi(HBasicBlock* block) {
if (block_cond->GetLeft() != dominator_cond->GetLeft() ||
block_cond->GetRight() != dominator_cond->GetRight() ||
- block_cond->GetOppositeCondition() != dominator_cond->GetCondition()) {
+ block_cond->GetOppositeCondition() != dominator_cond->GetCondition() ||
+ block_cond->GetBias() != dominator_cond->GetBias()) {
return;
}
}
diff --git a/libartservice/service/java/com/android/server/art/PreRebootDexoptJob.java b/libartservice/service/java/com/android/server/art/PreRebootDexoptJob.java
index b7f47543fc..51a01b363d 100644
--- a/libartservice/service/java/com/android/server/art/PreRebootDexoptJob.java
+++ b/libartservice/service/java/com/android/server/art/PreRebootDexoptJob.java
@@ -17,6 +17,7 @@
package com.android.server.art;
import static com.android.server.art.model.ArtFlags.ScheduleStatus;
+import static com.android.server.art.prereboot.PreRebootDriver.PreRebootResult;
import static com.android.server.art.proto.PreRebootStats.Status;
import android.annotation.NonNull;
@@ -158,9 +159,10 @@ public class PreRebootDexoptJob implements ArtServiceJobInterface {
// return value of `onStopJob` will be respected, and this call will be ignored.
jobService.jobFinished(params, false /* wantsReschedule */);
};
- // No need to handle exceptions thrown by the future because exceptions are handled inside
- // the future itself.
- startLocked(onJobFinishedLocked);
+ startLocked(onJobFinishedLocked).exceptionally(t -> {
+ AsLog.e("Fatal error", t);
+ return null;
+ });
}
@Override
@@ -357,10 +359,15 @@ public class PreRebootDexoptJob implements ArtServiceJobInterface {
var cancellationSignal = mCancellationSignal = new CancellationSignal();
mRunningJob = new CompletableFuture().runAsync(() -> {
markHasStarted(true);
+ PreRebootStatsReporter statsReporter = mInjector.getStatsReporter();
try {
- mInjector.getPreRebootDriver().run(otaSlot, mapSnapshotsForOta, cancellationSignal);
+ statsReporter.recordJobStarted();
+ PreRebootResult result = mInjector.getPreRebootDriver().run(
+ otaSlot, mapSnapshotsForOta, cancellationSignal);
+ statsReporter.recordJobEnded(result);
} catch (RuntimeException e) {
- AsLog.e("Fatal error", e);
+ statsReporter.recordJobEnded(new PreRebootResult(false /* success */));
+ throw e;
} finally {
synchronized (this) {
if (onJobFinishedLocked != null) {
diff --git a/libartservice/service/java/com/android/server/art/prereboot/PreRebootDriver.java b/libartservice/service/java/com/android/server/art/prereboot/PreRebootDriver.java
index 7c1a1c55fa..c29e0b4b2c 100644
--- a/libartservice/service/java/com/android/server/art/prereboot/PreRebootDriver.java
+++ b/libartservice/service/java/com/android/server/art/prereboot/PreRebootDriver.java
@@ -86,20 +86,16 @@ public class PreRebootDriver {
}
/**
- * Runs Pre-reboot Dexopt and returns whether it is successful. Returns false if Pre-reboot
- * dexopt failed, the system requirement check failed, or system requirements are not met.
+ * Runs Pre-reboot Dexopt and returns the result.
*
* @param otaSlot The slot that contains the OTA update, "_a" or "_b", or null for a Mainline
* update.
* @param mapSnapshotsForOta Whether to map/unmap snapshots. Only applicable to an OTA update.
*/
- public boolean run(@Nullable String otaSlot, boolean mapSnapshotsForOta,
+ public @NonNull PreRebootResult run(@Nullable String otaSlot, boolean mapSnapshotsForOta,
@NonNull CancellationSignal cancellationSignal) {
- var statsReporter = new PreRebootStatsReporter();
- boolean success = false;
boolean systemRequirementCheckFailed = false;
try {
- statsReporter.recordJobStarted();
try (var snapshot = mInjector.getPackageManagerLocal().withFilteredSnapshot()) {
BatchDexoptParams params = mInjector.getArtManagerLocal().getBatchDexoptParams(
snapshot, ReasonMapping.REASON_PRE_REBOOT_DEXOPT, cancellationSignal);
@@ -108,8 +104,7 @@ public class PreRebootDriver {
runFromChroot(cancellationSignal, snapshot, params);
}
}
- success = true;
- return true;
+ return new PreRebootResult(true /* success */);
} catch (RemoteException e) {
Utils.logArtdException(e);
} catch (ServiceSpecificException e) {
@@ -139,11 +134,9 @@ public class PreRebootDriver {
Utils.logArtdException(e);
} catch (ServiceSpecificException | IOException e) {
AsLog.e("Failed to tear down chroot", e);
- } finally {
- statsReporter.recordJobEnded(success, systemRequirementCheckFailed);
}
}
- return false;
+ return new PreRebootResult(false /* success */, systemRequirementCheckFailed);
}
public void test() {
@@ -257,6 +250,16 @@ public class PreRebootDriver {
}
/**
+ * @param success whether Pre-reboot Dexopt is successful. False if Pre-reboot dexopt failed,
+ * the system requirement check failed, or system requirements are not met.
+ */
+ public record PreRebootResult(boolean success, boolean systemRequirementCheckFailed) {
+ public PreRebootResult(boolean success) {
+ this(success, false /* systemRequirementCheckFailed */);
+ }
+ }
+
+ /**
* Injector pattern for testing purpose.
*
* @hide
diff --git a/libartservice/service/java/com/android/server/art/prereboot/PreRebootStatsReporter.java b/libartservice/service/java/com/android/server/art/prereboot/PreRebootStatsReporter.java
index fbf242db62..ec5c1acf31 100644
--- a/libartservice/service/java/com/android/server/art/prereboot/PreRebootStatsReporter.java
+++ b/libartservice/service/java/com/android/server/art/prereboot/PreRebootStatsReporter.java
@@ -16,6 +16,7 @@
package com.android.server.art.prereboot;
+import static com.android.server.art.prereboot.PreRebootDriver.PreRebootResult;
import static com.android.server.art.proto.PreRebootStats.JobRun;
import static com.android.server.art.proto.PreRebootStats.JobType;
import static com.android.server.art.proto.PreRebootStats.Status;
@@ -141,7 +142,7 @@ public class PreRebootStatsReporter {
}
}
- public void recordJobEnded(boolean success, boolean systemRequirementCheckFailed) {
+ public void recordJobEnded(@NonNull PreRebootResult result) {
PreRebootStats.Builder statsBuilder = load();
if (statsBuilder.getStatus() == Status.STATUS_UNKNOWN) {
// Failed to load, the error is already logged.
@@ -157,7 +158,7 @@ public class PreRebootStatsReporter {
mInjector.getCurrentTimeMillis());
Status status;
- if (success) {
+ if (result.success()) {
// The job is cancelled if it hasn't done package scanning (total package count is 0),
// or it's interrupted in the middle of package processing (package counts don't add up
// to the total).
@@ -172,7 +173,7 @@ public class PreRebootStatsReporter {
status = Status.STATUS_CANCELLED;
}
} else {
- if (systemRequirementCheckFailed) {
+ if (result.systemRequirementCheckFailed()) {
status = Status.STATUS_ABORTED_SYSTEM_REQUIREMENTS;
} else {
status = Status.STATUS_FAILED;
diff --git a/libartservice/service/javatests/com/android/server/art/PreRebootDexoptJobTest.java b/libartservice/service/javatests/com/android/server/art/PreRebootDexoptJobTest.java
index 4aaf1d5be9..0d99db20e7 100644
--- a/libartservice/service/javatests/com/android/server/art/PreRebootDexoptJobTest.java
+++ b/libartservice/service/javatests/com/android/server/art/PreRebootDexoptJobTest.java
@@ -17,6 +17,7 @@
package com.android.server.art;
import static com.android.server.art.PreRebootDexoptJob.JOB_ID;
+import static com.android.server.art.prereboot.PreRebootDriver.PreRebootResult;
import static com.google.common.truth.Truth.assertThat;
@@ -236,7 +237,7 @@ public class PreRebootDexoptJobTest {
when(mPreRebootDriver.run(any(), eq(true) /* mapSnapshotsForOta */, any()))
.thenAnswer(invocation -> {
jobStarted.release();
- return true;
+ return new PreRebootResult(true /* success */);
});
when(ArtJni.setProperty("dalvik.vm.pre-reboot.has-started", "true"))
@@ -259,7 +260,7 @@ public class PreRebootDexoptJobTest {
@Test
public void testSyncStart() throws Exception {
when(mPreRebootDriver.run(any(), eq(false) /* mapSnapshotsForOta */, any()))
- .thenReturn(true);
+ .thenReturn(new PreRebootResult(true /* success */));
CompletableFuture<Void> future = mPreRebootDexoptJob.onUpdateReadyStartNow(
null /* otaSlot */, false /* mapSnapshotsForOta */);
@@ -276,7 +277,7 @@ public class PreRebootDexoptJobTest {
cancellationSignal.setOnCancelListener(() -> dexoptCancelled.release());
assertThat(dexoptCancelled.tryAcquire(TIMEOUT_SEC, TimeUnit.SECONDS)).isTrue();
jobExited.release();
- return true;
+ return new PreRebootResult(true /* success */);
});
mPreRebootDexoptJob.onUpdateReadyImpl(null /* otaSlot */);
@@ -297,7 +298,7 @@ public class PreRebootDexoptJobTest {
cancellationSignal.setOnCancelListener(() -> dexoptCancelled.release());
assertThat(dexoptCancelled.tryAcquire(TIMEOUT_SEC, TimeUnit.SECONDS)).isTrue();
jobExited.release();
- return true;
+ return new PreRebootResult(true /* success */);
});
CompletableFuture<Void> future = mPreRebootDexoptJob.onUpdateReadyStartNow(
@@ -314,7 +315,8 @@ public class PreRebootDexoptJobTest {
mPreRebootDexoptJob.onUpdateReadyImpl("_b" /* otaSlot */);
mPreRebootDexoptJob.onUpdateReadyImpl(null /* otaSlot */);
- when(mPreRebootDriver.run(eq("_b"), anyBoolean(), any())).thenReturn(true);
+ when(mPreRebootDriver.run(eq("_b"), anyBoolean(), any()))
+ .thenReturn(new PreRebootResult(true /* success */));
mPreRebootDexoptJob.onStartJobImpl(mJobService, mJobParameters);
mPreRebootDexoptJob.waitForRunningJob();
@@ -325,7 +327,8 @@ public class PreRebootDexoptJobTest {
mPreRebootDexoptJob.onUpdateReadyImpl(null /* otaSlot */);
mPreRebootDexoptJob.onUpdateReadyImpl("_a" /* otaSlot */);
- when(mPreRebootDriver.run(eq("_a"), anyBoolean(), any())).thenReturn(true);
+ when(mPreRebootDriver.run(eq("_a"), anyBoolean(), any()))
+ .thenReturn(new PreRebootResult(true /* success */));
mPreRebootDexoptJob.onStartJobImpl(mJobService, mJobParameters);
mPreRebootDexoptJob.waitForRunningJob();
@@ -336,7 +339,8 @@ public class PreRebootDexoptJobTest {
mPreRebootDexoptJob.onUpdateReadyImpl(null /* otaSlot */);
mPreRebootDexoptJob.onUpdateReadyImpl(null /* otaSlot */);
- when(mPreRebootDriver.run(isNull(), anyBoolean(), any())).thenReturn(true);
+ when(mPreRebootDriver.run(isNull(), anyBoolean(), any()))
+ .thenReturn(new PreRebootResult(true /* success */));
mPreRebootDexoptJob.onStartJobImpl(mJobService, mJobParameters);
mPreRebootDexoptJob.waitForRunningJob();
@@ -347,7 +351,8 @@ public class PreRebootDexoptJobTest {
mPreRebootDexoptJob.onUpdateReadyImpl("_b" /* otaSlot */);
mPreRebootDexoptJob.onUpdateReadyImpl("_b" /* otaSlot */);
- when(mPreRebootDriver.run(eq("_b"), anyBoolean(), any())).thenReturn(true);
+ when(mPreRebootDriver.run(eq("_b"), anyBoolean(), any()))
+ .thenReturn(new PreRebootResult(true /* success */));
mPreRebootDexoptJob.onStartJobImpl(mJobService, mJobParameters);
mPreRebootDexoptJob.waitForRunningJob();
@@ -375,7 +380,7 @@ public class PreRebootDexoptJobTest {
when(mPreRebootDriver.run(any(), anyBoolean(), any())).thenAnswer(invocation -> {
// Simulate that the job takes a while to exit, no matter it's cancelled or not.
assertThat(jobBlocker.tryAcquire(TIMEOUT_SEC, TimeUnit.SECONDS)).isTrue();
- return true;
+ return new PreRebootResult(true /* success */);
});
// An update arrives. A job is scheduled.
@@ -461,7 +466,7 @@ public class PreRebootDexoptJobTest {
cancellationSignal.setOnCancelListener(() -> dexoptCancelled.release());
assertThat(dexoptCancelled.tryAcquire(TIMEOUT_SEC, TimeUnit.SECONDS)).isTrue();
jobExited.release();
- return true;
+ return new PreRebootResult(true /* success */);
});
// An update arrives. A job is scheduled.
diff --git a/libartservice/service/javatests/com/android/server/art/prereboot/PreRebootStatsReporterTest.java b/libartservice/service/javatests/com/android/server/art/prereboot/PreRebootStatsReporterTest.java
index 59291b7471..846a835b75 100644
--- a/libartservice/service/javatests/com/android/server/art/prereboot/PreRebootStatsReporterTest.java
+++ b/libartservice/service/javatests/com/android/server/art/prereboot/PreRebootStatsReporterTest.java
@@ -17,6 +17,7 @@
package com.android.server.art.prereboot;
import static com.android.server.art.model.DexoptStatus.DexContainerFileDexoptStatus;
+import static com.android.server.art.prereboot.PreRebootDriver.PreRebootResult;
import static com.android.server.art.proto.PreRebootStats.JobRun;
import static com.android.server.art.proto.PreRebootStats.JobType;
import static com.android.server.art.proto.PreRebootStats.Status;
@@ -118,7 +119,7 @@ public class PreRebootStatsReporterTest {
.build());
doReturn(300l).when(mInjector).getCurrentTimeMillis();
- reporter.recordJobEnded(true /* success */, false /* systemRequirementCheckFailed */);
+ reporter.recordJobEnded(new PreRebootResult(true /* success */));
checkProto(PreRebootStats.newBuilder()
.setStatus(Status.STATUS_CANCELLED)
.setJobType(JobType.JOB_TYPE_MAINLINE)
@@ -174,7 +175,7 @@ public class PreRebootStatsReporterTest {
.build());
doReturn(600l).when(mInjector).getCurrentTimeMillis();
- reporter.recordJobEnded(true /* success */, false /* systemRequirementCheckFailed */);
+ reporter.recordJobEnded(new PreRebootResult(true /* success */));
checkProto(PreRebootStats.newBuilder()
.setStatus(Status.STATUS_FINISHED)
.setJobType(JobType.JOB_TYPE_MAINLINE)
@@ -290,7 +291,7 @@ public class PreRebootStatsReporterTest {
.build());
doReturn(300l).when(mInjector).getCurrentTimeMillis();
- reporter.recordJobEnded(true /* success */, false /* systemRequirementCheckFailed */);
+ reporter.recordJobEnded(new PreRebootResult(true /* success */));
checkProto(PreRebootStats.newBuilder()
.setStatus(Status.STATUS_FINISHED)
.setJobType(JobType.JOB_TYPE_OTA)
@@ -350,7 +351,8 @@ public class PreRebootStatsReporterTest {
.build());
doReturn(300l).when(mInjector).getCurrentTimeMillis();
- reporter.recordJobEnded(false /* success */, systemRequirementCheckFailed);
+ reporter.recordJobEnded(
+ new PreRebootResult(false /* success */, systemRequirementCheckFailed));
checkProto(PreRebootStats.newBuilder()
.setStatus(systemRequirementCheckFailed
? Status.STATUS_ABORTED_SYSTEM_REQUIREMENTS
diff --git a/runtime/base/mutex.cc b/runtime/base/mutex.cc
index 26a665bd41..9d7b20052b 100644
--- a/runtime/base/mutex.cc
+++ b/runtime/base/mutex.cc
@@ -1023,6 +1023,7 @@ void ReaderWriterMutex::WakeupToRespondToEmptyCheckpoint() {
ConditionVariable::ConditionVariable(const char* name, Mutex& guard)
: name_(name), guard_(guard) {
+ DCHECK(name != nullptr);
#if ART_USE_FUTEXES
DCHECK_EQ(0, sequence_.load(std::memory_order_relaxed));
num_waiters_ = 0;
@@ -1120,7 +1121,7 @@ void ConditionVariable::WaitHoldingLocks(Thread* self) {
// EAGAIN == EWOULDBLK, so we let the caller try again.
// EINTR implies a signal was sent to this thread.
if ((errno != EINTR) && (errno != EAGAIN)) {
- PLOG(FATAL) << "futex wait failed for " << name_;
+ PLOG(FATAL) << "futex wait failed for " << name_ << ": " << strerror(errno);
}
}
SleepIfRuntimeDeleted(self);
diff --git a/runtime/hidden_api.cc b/runtime/hidden_api.cc
index 7f80c03a2a..6e4a12d3cc 100644
--- a/runtime/hidden_api.cc
+++ b/runtime/hidden_api.cc
@@ -364,7 +364,7 @@ void MemberSignature::WarnAboutAccess(AccessMethod access_method,
if (log_warning_count_ > kMaxLogWarnings) {
return;
}
- LOG(policy == EnforcementPolicy::kEnabled ? ERROR : WARNING)
+ LOG(access_denied ? (policy == EnforcementPolicy::kEnabled ? ERROR : WARNING) : INFO)
<< "hiddenapi: Accessing hidden " << (type_ == kField ? "field " : "method ")
<< Dumpable<MemberSignature>(*this)
<< " (runtime_flags=" << FormatHiddenApiRuntimeFlags(runtime_flags)
diff --git a/test/2038-hiddenapi-jvmti-ext/run.py b/test/2038-hiddenapi-jvmti-ext/run.py
index c3f6d8fb72..49a7ef365a 100644
--- a/test/2038-hiddenapi-jvmti-ext/run.py
+++ b/test/2038-hiddenapi-jvmti-ext/run.py
@@ -18,6 +18,5 @@
def run(ctx, args):
ctx.default_run(args, jvmti=True)
- # Delete hiddenapi's denial errors which go to stderr on host.
- if args.host:
- ctx.run(fr"sed -i -E '/ E dalvikvm.* hiddenapi: /d' '{args.stderr_file}'")
+ # Ignore hiddenapi's denial errors which go to stderr on host and qemu (but not on device).
+ ctx.run(fr"sed -i -E '/ E dalvikvm.* hiddenapi: /d' '{args.stderr_file}'")
diff --git a/test/2255-checker-branch-redirection/src/Main.java b/test/2255-checker-branch-redirection/src/Main.java
index bfc6381942..a2c04ef6e0 100644
--- a/test/2255-checker-branch-redirection/src/Main.java
+++ b/test/2255-checker-branch-redirection/src/Main.java
@@ -32,6 +32,15 @@ public class Main {
assertEquals(30, $noinline$testEliminateIfParameterOppositeCondition(20, 10, 20 < 10));
assertEquals(40, $noinline$testEliminateIfParameterOppositeCondition_2(20, 40, 20 < 40));
assertEquals(30, $noinline$testEliminateIfParameterOppositeCondition_2(20, 10, 20 < 10));
+
+ assertEquals(2, $noinline$testEliminateIfFp(20.0, 40.0));
+ assertEquals(3, $noinline$testEliminateIfFp(20.0, 10.0));
+ assertEquals(3, $noinline$testEliminateIfFp(20.0, Double.NaN));
+ assertEquals(3, $noinline$testEliminateIfFp(Double.NaN, 10.0));
+ assertEquals(3, $noinline$testDoNotEliminateIfOppositeCondFpWrongBias(20.0, 40.0));
+ assertEquals(2, $noinline$testDoNotEliminateIfOppositeCondFpWrongBias(20.0, 10.0));
+ assertEquals(3, $noinline$testDoNotEliminateIfOppositeCondFpWrongBias(20.0, Double.NaN));
+ assertEquals(3, $noinline$testDoNotEliminateIfOppositeCondFpWrongBias(Double.NaN, 10.0));
}
private static int $noinline$emptyMethod(int a) {
@@ -274,6 +283,50 @@ public class Main {
return result;
}
+ /// CHECK-START: int Main.$noinline$testEliminateIfFp(double, double) dead_code_elimination$after_gvn (before)
+ /// CHECK: If
+ /// CHECK: If
+
+ /// CHECK-START: int Main.$noinline$testEliminateIfFp(double, double) dead_code_elimination$after_gvn (after)
+ /// CHECK: If
+ /// CHECK-NOT: If
+ private static int $noinline$testEliminateIfFp(double a, double b) {
+ int result = 0;
+ if (a < b) {
+ $noinline$emptyMethod(0);
+ } else {
+ $noinline$emptyMethod(1);
+ }
+ if (a < b) {
+ result += $noinline$emptyMethod(2);
+ } else {
+ result += $noinline$emptyMethod(3);
+ }
+ return result;
+ }
+
+ /// CHECK-START: int Main.$noinline$testDoNotEliminateIfOppositeCondFpWrongBias(double, double) dead_code_elimination$initial (before)
+ /// CHECK: If
+ /// CHECK: If
+
+ /// CHECK-START: int Main.$noinline$testDoNotEliminateIfOppositeCondFpWrongBias(double, double) dead_code_elimination$initial (after)
+ /// CHECK: If
+ /// CHECK: If
+ private static int $noinline$testDoNotEliminateIfOppositeCondFpWrongBias(double a, double b) {
+ int result = 0;
+ if (a < b) {
+ $noinline$emptyMethod(0);
+ } else {
+ $noinline$emptyMethod(1);
+ }
+ if (a >= b) {
+ result += $noinline$emptyMethod(2);
+ } else {
+ result += $noinline$emptyMethod(3);
+ }
+ return result;
+ }
+
public static void assertEquals(int expected, int result) {
if (expected != result) {
throw new Error("Expected: " + expected + ", found: " + result);
diff --git a/test/674-hiddenapi/run.py b/test/674-hiddenapi/run.py
index ea0cd1d3b5..7967a46047 100644
--- a/test/674-hiddenapi/run.py
+++ b/test/674-hiddenapi/run.py
@@ -25,6 +25,5 @@ def run(ctx, args):
ctx.run(fr"sed -i -E '/(JNI_OnLoad|JNI_OnUnload)/d' '{args.stdout_file}'")
- # Delete hiddenapi's denial errors which go to stderr on host.
- if args.host:
- ctx.run(fr"sed -i -E '/ E dalvikvm.* hiddenapi: /d' '{args.stderr_file}'")
+ # Ignore hiddenapi's denial errors which go to stderr on host and qemu (but not on device).
+ ctx.run(fr"sed -i -E '/ E dalvikvm.* hiddenapi: /d' '{args.stderr_file}'")
diff --git a/test/817-hiddenapi/run.py b/test/817-hiddenapi/run.py
index 14670eb0c5..a394a4ea29 100644
--- a/test/817-hiddenapi/run.py
+++ b/test/817-hiddenapi/run.py
@@ -21,6 +21,5 @@ def run(ctx, args):
# be emitted. If so, remove it.
ctx.run(fr"sed -i '/^JNI_OnUnload called$/d' '{args.stdout_file}'")
- # Delete hiddenapi's denial errors which go to stderr on host.
- if args.host:
- ctx.run(fr"sed -i -E '/ E dalvikvm.* hiddenapi: /d' '{args.stderr_file}'")
+ # Ignore hiddenapi's denial errors which go to stderr on host and qemu (but not on device).
+ ctx.run(fr"sed -i -E '/ E dalvikvm.* hiddenapi: /d' '{args.stderr_file}'")
diff --git a/test/999-redefine-hiddenapi/run.py b/test/999-redefine-hiddenapi/run.py
index c3f6d8fb72..49a7ef365a 100644
--- a/test/999-redefine-hiddenapi/run.py
+++ b/test/999-redefine-hiddenapi/run.py
@@ -18,6 +18,5 @@
def run(ctx, args):
ctx.default_run(args, jvmti=True)
- # Delete hiddenapi's denial errors which go to stderr on host.
- if args.host:
- ctx.run(fr"sed -i -E '/ E dalvikvm.* hiddenapi: /d' '{args.stderr_file}'")
+ # Ignore hiddenapi's denial errors which go to stderr on host and qemu (but not on device).
+ ctx.run(fr"sed -i -E '/ E dalvikvm.* hiddenapi: /d' '{args.stderr_file}'")