changeset 20021:4b6965a278cf

Fix allocation counter issue where the counters sometimes gives way too high values for allocated bytes
author Stefan Anzinger <stefan.anzinger@oracle.com>
date Tue, 24 Mar 2015 14:36:57 +0100
parents af1e4c16b00f
children eebf140fa6e4
files graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCounterOp.java
diffstat 2 files changed, 49 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Tue Mar 24 12:01:58 2015 +0100
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Tue Mar 24 14:36:57 2015 +0100
@@ -728,6 +728,7 @@
         public static final AMD64MOp IMUL = new AMD64MOp("IMUL", 0xF7, 5);
         public static final AMD64MOp DIV  = new AMD64MOp("DIV",  0xF7, 6);
         public static final AMD64MOp IDIV = new AMD64MOp("IDIV", 0xF7, 7);
+        public static final AMD64MOp INC  = new AMD64MOp("INC",  0xFF, 0);
         // @formatter:on
 
         private final int ext;
@@ -2412,4 +2413,12 @@
         emitOperandHelper(1, src);
     }
 
+    /**
+     * Emits an instruction which is considered to be illegal. This is used if we deliberately want
+     * to crash the program (debugging etc.).
+     */
+    public void illegal() {
+        emitByte(0x0f);
+        emitByte(0x0b);
+    }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCounterOp.java	Tue Mar 24 12:01:58 2015 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCounterOp.java	Tue Mar 24 14:36:57 2015 +0100
@@ -24,6 +24,11 @@
 
 import static com.oracle.graal.amd64.AMD64.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
+import static com.oracle.graal.asm.NumUtil.*;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.*;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.AMD64MOp.*;
+import static com.oracle.graal.asm.amd64.AMD64Assembler.OperandSize.*;
+import static com.oracle.graal.compiler.common.GraalInternalError.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -54,7 +59,19 @@
         AMD64MacroAssembler masm = (AMD64MacroAssembler) crb.asm;
         TargetDescription target = crb.target;
 
-        Register scratch = rax;
+        Register scratch;
+        // It can happen that the rax register is the increment register, in this case we do not
+        // want to spill it to the stack.
+        if (!contains(increments, rax)) {
+            scratch = rax;
+        } else if (!contains(increments, rbx)) {
+            scratch = rbx;
+        } else {
+            // In this case rax and rbx are used as increment. Either we implement a third register
+            // or we implement a spillover the value from rax to rbx or vice versa during
+            // emitIncrement().
+            throw unimplemented("RAX and RBX are increment registers a the same time, spilling over the scratch register is not supported right now");
+        }
 
         // address for counters array
         AMD64Address countersArrayAddr = new AMD64Address(thread, config.graalCountersThreadOffset);
@@ -72,14 +89,32 @@
         masm.movq(scratch, (AMD64Address) crb.asAddress(backupSlot));
     }
 
-    private static void emitIncrement(AMD64MacroAssembler masm, Register countersArrayReg, Value increment, int displacement) {
+    /**
+     * Tests if the array contains the register.
+     */
+    private static boolean contains(Value[] increments, Register register) {
+        for (Value increment : increments) {
+            if (isRegister(increment) && asRegister(increment).equals(register)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static void emitIncrement(AMD64MacroAssembler masm, Register countersArrayReg, Value incrementValue, int displacement) {
         // address for counter value
         AMD64Address counterAddr = new AMD64Address(countersArrayReg, displacement);
         // increment counter (in memory)
-        if (isConstant(increment)) {
-            masm.incrementl(counterAddr, asInt(asConstant(increment)));
+        if (isConstant(incrementValue)) {
+            int increment = asInt(asConstant(incrementValue));
+            if (increment == 1) {
+                INC.emit(masm, QWORD, counterAddr);
+            } else {
+                ADD.getMIOpcode(QWORD, isByte(increment)).emit(masm, QWORD, counterAddr, increment);
+            }
         } else {
-            masm.addq(counterAddr, asRegister(increment));
+            masm.addq(counterAddr, asRegister(incrementValue));
         }
+
     }
 }