Mercurial > hg > truffle
diff graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java @ 9885:ed86945795d5
Add Compressed Oops support in LIR
author | Christos Kotselidis <christos.kotselidis@oracle.com> |
---|---|
date | Tue, 04 Jun 2013 18:06:57 +0200 |
parents | cbf274a92e5b |
children | 9d0031cf5df9 |
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Tue Jun 04 17:14:51 2013 +0200 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Tue Jun 04 18:06:57 2013 +0200 @@ -45,9 +45,18 @@ import com.oracle.graal.lir.StandardOp.ParametersOp; import com.oracle.graal.lir.StandardOp.PlaceholderOp; import com.oracle.graal.lir.amd64.*; +import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp; +import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapCompressedOp; import com.oracle.graal.lir.amd64.AMD64Move.CompareAndSwapOp; +import com.oracle.graal.lir.amd64.AMD64Move.LoadCompressedOop; +import com.oracle.graal.lir.amd64.AMD64Move.LoadOp; import com.oracle.graal.lir.amd64.AMD64Move.MoveFromRegOp; +import com.oracle.graal.lir.amd64.AMD64Move.StoreCompressedOop; +import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp; +import com.oracle.graal.lir.amd64.AMD64Move.StoreOp; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; /** @@ -391,4 +400,78 @@ op.savedRbp = savedRbp; } } + + private static boolean isCompressCandidate(DeoptimizingNode access) { + return access != null && ((HeapAccess) access).compress(); + } + + @Override + public Variable emitLoad(Kind kind, Value address, DeoptimizingNode access) { + AMD64AddressValue loadAddress = asAddressValue(address); + Variable result = newVariable(kind); + assert access != null || access instanceof HeapAccess; + if (runtime().config.useCompressedOops && isCompressCandidate(access)) { + assert kind == Kind.Object; + Variable scratch = newVariable(Kind.Long); + append(new LoadCompressedOop(kind, result, scratch, loadAddress, access != null ? state(access) : null, runtime().config.narrowOopBase, runtime().config.narrowOopShift, + runtime().config.logMinObjAlignment)); + } else { + append(new LoadOp(kind, result, loadAddress, access != null ? state(access) : null)); + } + return result; + } + + @Override + public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode access) { + AMD64AddressValue storeAddress = asAddressValue(address); + LIRFrameState state = access != null ? state(access) : null; + if (isConstant(inputVal)) { + Constant c = asConstant(inputVal); + if (canStoreConstant(c)) { + append(new StoreConstantOp(kind, storeAddress, c, state, runtime().config.useCompressedOops && isCompressCandidate(access))); + return; + } + } + Variable input = load(inputVal); + if (runtime().config.useCompressedOops && isCompressCandidate(access)) { + assert kind == Kind.Object; + Variable scratch = newVariable(Kind.Long); + append(new StoreCompressedOop(kind, storeAddress, input, scratch, state, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment)); + } else { + append(new StoreOp(kind, storeAddress, input, state)); + } + } + + @Override + public void visitCompareAndSwap(CompareAndSwapNode node) { + Kind kind = node.newValue().kind(); + assert kind == node.expected().kind(); + + Value expected = loadNonConst(operand(node.expected())); + Variable newValue = load(operand(node.newValue())); + + AMD64AddressValue address; + int displacement = node.displacement(); + Value index = operand(node.offset()); + if (isConstant(index) && NumUtil.isInt(asConstant(index).asLong() + displacement)) { + assert !runtime.needsDataPatch(asConstant(index)); + displacement += (int) asConstant(index).asLong(); + address = new AMD64AddressValue(kind, load(operand(node.object())), displacement); + } else { + address = new AMD64AddressValue(kind, load(operand(node.object())), load(index), Scale.Times1, displacement); + } + + RegisterValue raxRes = AMD64.rax.asValue(kind); + emitMove(raxRes, expected); + if (runtime().config.useCompressedOops && node.compress()) { + assert kind == Kind.Object; + Variable scratch = newVariable(Kind.Long); + append(new CompareAndSwapCompressedOp(raxRes, address, raxRes, newValue, scratch, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment)); + } else { + append(new CompareAndSwapOp(raxRes, address, raxRes, newValue)); + } + Variable result = newVariable(node.kind()); + append(new CondMoveOp(result, Condition.EQ, load(Constant.TRUE), Constant.FALSE)); + setResult(node, result); + } }