Revert^2 "Prevent overflow for AOT hotness counters"

Fixed bug where sbc usage was incorrect. sbc does -1 + carry.

Test: test/run-test --always-clean --runtime-option -Xcheck:jni --64 674-hotness-compiled
Test: test/run-test --always-clean --runtime-option -Xcheck:jni 674-hotness-compiled
Bug: 139883463

This reverts commit 7ab07777b08db86dda2891f3e7ae15df8f25a599.

Change-Id: I6f8ac0320592a94314386b04cdb0c7e0e6da6994
diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc
index a299ece..502ff60 100644
--- a/compiler/optimizing/code_generator_arm64.cc
+++ b/compiler/optimizing/code_generator_arm64.cc
@@ -1070,6 +1070,8 @@
     Register temp = temps.AcquireX();
     __ Ldrh(temp, MemOperand(kArtMethodRegister, ArtMethod::HotnessCountOffset().Int32Value()));
     __ Add(temp, temp, 1);
+      // Subtract one if the counter would overflow.
+    __ Sub(temp, temp, Operand(temp, LSR, 16));
     __ Strh(temp, MemOperand(kArtMethodRegister, ArtMethod::HotnessCountOffset().Int32Value()));
   }
 
@@ -3177,6 +3179,8 @@
       __ Ldr(temp1, MemOperand(sp, 0));
       __ Ldrh(temp2, MemOperand(temp1, ArtMethod::HotnessCountOffset().Int32Value()));
       __ Add(temp2, temp2, 1);
+      // Subtract one if the counter would overflow.
+      __ Sub(temp2, temp2, Operand(temp2, LSR, 16));
       __ Strh(temp2, MemOperand(temp1, ArtMethod::HotnessCountOffset().Int32Value()));
     }
     GenerateSuspendCheck(info->GetSuspendCheck(), successor);
diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc
index b3141bf..02286d8 100644
--- a/compiler/optimizing/code_generator_arm_vixl.cc
+++ b/compiler/optimizing/code_generator_arm_vixl.cc
@@ -2087,8 +2087,12 @@
   if (GetCompilerOptions().CountHotnessInCompiledCode()) {
     UseScratchRegisterScope temps(GetVIXLAssembler());
     vixl32::Register temp = temps.Acquire();
+    static_assert(ArtMethod::MaxCounter() == 0xFFFF, "asm is probably wrong");
+    // Load with sign extend to set the high bits for integer overflow check.
     __ Ldrh(temp, MemOperand(kMethodRegister, ArtMethod::HotnessCountOffset().Int32Value()));
     __ Add(temp, temp, 1);
+    // Subtract one if the counter would overflow.
+    __ Sub(temp, temp, Operand(temp, ShiftType::LSR, 16));
     __ Strh(temp, MemOperand(kMethodRegister, ArtMethod::HotnessCountOffset().Int32Value()));
   }
 
@@ -2497,8 +2501,11 @@
       vixl32::Register temp = temps.Acquire();
       __ Push(vixl32::Register(kMethodRegister));
       GetAssembler()->LoadFromOffset(kLoadWord, kMethodRegister, sp, kArmWordSize);
+      // Load with sign extend to set the high bits for integer overflow check.
       __ Ldrh(temp, MemOperand(kMethodRegister, ArtMethod::HotnessCountOffset().Int32Value()));
       __ Add(temp, temp, 1);
+      // Subtract one if the counter would overflow.
+      __ Sub(temp, temp, Operand(temp, ShiftType::LSR, 16));
       __ Strh(temp, MemOperand(kMethodRegister, ArtMethod::HotnessCountOffset().Int32Value()));
       __ Pop(vixl32::Register(kMethodRegister));
     }
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index 4ab398e..797fe32 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -1078,8 +1078,15 @@
   DCHECK(GetCompilerOptions().GetImplicitStackOverflowChecks());
 
   if (GetCompilerOptions().CountHotnessInCompiledCode()) {
-    __ addw(Address(kMethodRegisterArgument, ArtMethod::HotnessCountOffset().Int32Value()),
+    NearLabel overflow;
+    __ cmpw(Address(kMethodRegisterArgument,
+                    ArtMethod::HotnessCountOffset().Int32Value()),
+            Immediate(ArtMethod::MaxCounter()));
+    __ j(kEqual, &overflow);
+    __ addw(Address(kMethodRegisterArgument,
+                    ArtMethod::HotnessCountOffset().Int32Value()),
             Immediate(1));
+    __ Bind(&overflow);
   }
 
   if (!skip_overflow_check) {
@@ -1385,7 +1392,13 @@
     if (codegen_->GetCompilerOptions().CountHotnessInCompiledCode()) {
       __ pushl(EAX);
       __ movl(EAX, Address(ESP, kX86WordSize));
-      __ addw(Address(EAX, ArtMethod::HotnessCountOffset().Int32Value()), Immediate(1));
+          NearLabel overflow;
+      __ cmpw(Address(EAX, ArtMethod::HotnessCountOffset().Int32Value()),
+              Immediate(ArtMethod::MaxCounter()));
+      __ j(kEqual, &overflow);
+      __ addw(Address(EAX, ArtMethod::HotnessCountOffset().Int32Value()),
+              Immediate(1));
+      __ Bind(&overflow);
       __ popl(EAX);
     }
     GenerateSuspendCheck(info->GetSuspendCheck(), successor);
diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc
index a75c745..2d51f32 100644
--- a/compiler/optimizing/code_generator_x86_64.cc
+++ b/compiler/optimizing/code_generator_x86_64.cc
@@ -1349,9 +1349,15 @@
   DCHECK(GetCompilerOptions().GetImplicitStackOverflowChecks());
 
   if (GetCompilerOptions().CountHotnessInCompiledCode()) {
+    NearLabel overflow;
+    __ cmpw(Address(CpuRegister(kMethodRegisterArgument),
+                    ArtMethod::HotnessCountOffset().Int32Value()),
+            Immediate(ArtMethod::MaxCounter()));
+    __ j(kEqual, &overflow);
     __ addw(Address(CpuRegister(kMethodRegisterArgument),
                     ArtMethod::HotnessCountOffset().Int32Value()),
             Immediate(1));
+    __ Bind(&overflow);
   }
 
   if (!skip_overflow_check) {
@@ -1547,8 +1553,13 @@
   if (info != nullptr && info->IsBackEdge(*block) && info->HasSuspendCheck()) {
     if (codegen_->GetCompilerOptions().CountHotnessInCompiledCode()) {
       __ movq(CpuRegister(TMP), Address(CpuRegister(RSP), 0));
+      NearLabel overflow;
+      __ cmpw(Address(CpuRegister(TMP), ArtMethod::HotnessCountOffset().Int32Value()),
+              Immediate(ArtMethod::MaxCounter()));
+      __ j(kEqual, &overflow);
       __ addw(Address(CpuRegister(TMP), ArtMethod::HotnessCountOffset().Int32Value()),
               Immediate(1));
+      __ Bind(&overflow);
     }
     GenerateSuspendCheck(info->GetSuspendCheck(), successor);
     return;