Mercurial > hg > graal-jvmci-8
comparison graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/target/amd64/HotSpotAMD64Backend.java @ 5841:f84d11672a86
vtable dispatch inlining for megamorphic virtual calls now works and is enabled by default
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 16 Jul 2012 15:20:50 +0200 |
parents | f238fe91dc7f |
children | a432e6d43aa1 |
comparison
equal
deleted
inserted
replaced
5840:f565e8d4d200 | 5841:f84d11672a86 |
---|---|
110 final MethodCallTargetNode callTarget = x.callTarget(); | 110 final MethodCallTargetNode callTarget = x.callTarget(); |
111 final InvokeKind invokeKind = callTarget.invokeKind(); | 111 final InvokeKind invokeKind = callTarget.invokeKind(); |
112 Kind[] signature = MetaUtil.signatureToKinds(callTarget.targetMethod().signature(), callTarget.isStatic() ? null : callTarget.targetMethod().holder().kind()); | 112 Kind[] signature = MetaUtil.signatureToKinds(callTarget.targetMethod().signature(), callTarget.isStatic() ? null : callTarget.targetMethod().holder().kind()); |
113 CallingConvention cc = frameMap.registerConfig.getCallingConvention(JavaCall, signature, target(), false); | 113 CallingConvention cc = frameMap.registerConfig.getCallingConvention(JavaCall, signature, target(), false); |
114 frameMap.callsMethod(cc, JavaCall); | 114 frameMap.callsMethod(cc, JavaCall); |
115 | |
116 Value address = Constant.forLong(0L); | |
117 | |
118 ValueNode methodOopNode = null; | |
119 | |
120 if (callTarget.computedAddress() != null) { | |
121 // If a virtual dispatch address was computed, then an extra argument | |
122 // was append for passing the methodOop in RBX | |
123 methodOopNode = callTarget.arguments().remove(callTarget.arguments().size() - 1); | |
124 | |
125 if (invokeKind == Virtual) { | |
126 address = operand(callTarget.computedAddress()); | |
127 } else { | |
128 // An invokevirtual may have been canonicalized into an invokespecial; | |
129 // the methodOop argument is ignored in this case | |
130 } | |
131 } | |
132 | |
115 List<Value> argList = visitInvokeArguments(cc, callTarget.arguments()); | 133 List<Value> argList = visitInvokeArguments(cc, callTarget.arguments()); |
116 | 134 |
117 Value address = callTarget.address() == null ? Constant.forLong(0L) : operand(callTarget.address()); | 135 if (methodOopNode != null) { |
136 Value methodOopArg = operand(methodOopNode); | |
137 emitMove(methodOopArg, AMD64.rbx.asValue()); | |
138 argList.add(methodOopArg); | |
139 } | |
118 | 140 |
119 final Mark[] callsiteForStaticCallStub = {null}; | 141 final Mark[] callsiteForStaticCallStub = {null}; |
120 | |
121 if (invokeKind == Static || invokeKind == Special) { | 142 if (invokeKind == Static || invokeKind == Special) { |
122 lir.stubs.add(new AMD64Code() { | 143 lir.stubs.add(new AMD64Code() { |
123 public String description() { | 144 public String description() { |
124 return "static call stub for Invoke" + invokeKind; | 145 return "static call stub for Invoke" + invokeKind; |
125 } | 146 } |
143 } else { | 164 } else { |
144 // The mark for an invocation that uses an inline cache must be placed at the instruction | 165 // The mark for an invocation that uses an inline cache must be placed at the instruction |
145 // that loads the klassOop from the inline cache so that the C++ code can find it | 166 // that loads the klassOop from the inline cache so that the C++ code can find it |
146 // and replace the inline null value with Universe::non_oop_word() | 167 // and replace the inline null value with Universe::non_oop_word() |
147 assert invokeKind == Virtual || invokeKind == Interface; | 168 assert invokeKind == Virtual || invokeKind == Interface; |
148 if (callTarget.address() == null) { | 169 if (invokeKind == Virtual && callTarget.computedAddress() != null) { |
170 tasm.recordMark(MARK_INLINE_INVOKEVIRTUAL); | |
171 } else { | |
149 tasm.recordMark(invokeKind == Virtual ? MARK_INVOKEVIRTUAL : MARK_INVOKEINTERFACE); | 172 tasm.recordMark(invokeKind == Virtual ? MARK_INVOKEVIRTUAL : MARK_INVOKEINTERFACE); |
150 AMD64MacroAssembler masm = (AMD64MacroAssembler) tasm.asm; | 173 AMD64MacroAssembler masm = (AMD64MacroAssembler) tasm.asm; |
151 AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Object), Constant.NULL_OBJECT); | 174 AMD64Move.move(tasm, masm, AMD64.rax.asValue(Kind.Object), Constant.NULL_OBJECT); |
152 } else { | |
153 tasm.recordMark(MARK_INLINE_INVOKEVIRTUAL); | |
154 } | 175 } |
155 } | 176 } |
156 } | 177 } |
157 public void atCall(TargetMethodAssembler tasm) { | 178 public void atCall(TargetMethodAssembler tasm) { |
158 if (invokeKind == Static || invokeKind == Special) { | 179 if (invokeKind == Static || invokeKind == Special) { |