# HG changeset patch # User Lukas Stadler # Date 1282175226 25200 # Node ID 149b1d2316de155a7cc1f1e6234b880ae1181cf6 # Parent ed6bd46ad55e48d68855a66d46b06cd4d2403da1 basic invokeinterface and invokevirtual support diff -r ed6bd46ad55e -r 149b1d2316de c1x4hotspotsrc/HotSpotTest/src/jttTests.java --- a/c1x4hotspotsrc/HotSpotTest/src/jttTests.java Wed Aug 18 11:44:04 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotTest/src/jttTests.java Wed Aug 18 16:47:06 2010 -0700 @@ -4,7 +4,7 @@ public class jttTests { public static void main(String[] args) { - runTests(182, 182); + runTests(0, 200); Logger.info("total: " + executed + " tests executed, " + passed + " passed, " + failed + " failed"); } diff -r ed6bd46ad55e -r 149b1d2316de c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotProxy.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotProxy.java Wed Aug 18 11:44:04 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotProxy.java Wed Aug 18 16:47:06 2010 -0700 @@ -29,13 +29,14 @@ private enum CompilerObjectType { // this enum needs to have the same values as the one in c1x_Compiler.hpp - STUB(0x100000000000000l), - METHOD(0x200000000000000l), - CLASS(0x300000000000000l), - SYMBOL(0x400000000000000l), - CONSTANT_POOL(0x500000000000000l), - CONSTANT(0x600000000000000l), - TYPE_MASK(0xf00000000000000l); + STUB(0x100000000000000L), + METHOD(0x200000000000000L), + CLASS(0x300000000000000L), + SYMBOL(0x400000000000000L), + CONSTANT_POOL(0x500000000000000L), + CONSTANT(0x600000000000000L), + TYPE_MASK(0xf00000000000000L), + DUMMY_CONSTANT(0x6ffffffffffffffL); public final long bits; @@ -44,6 +45,8 @@ } } + public static final Long DUMMY_CONSTANT_OBJ = CompilerObjectType.DUMMY_CONSTANT.bits; + private static boolean isType(long id, CompilerObjectType type) { return (id & CompilerObjectType.TYPE_MASK.bits) == type.bits; } diff -r ed6bd46ad55e -r 149b1d2316de c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTargetMethod.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTargetMethod.java Wed Aug 18 11:44:04 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotTargetMethod.java Wed Aug 18 16:47:06 2010 -0700 @@ -20,7 +20,7 @@ import java.util.*; import com.sun.cri.ci.*; -import com.sun.cri.ci.CiTargetMethod.Site; +import com.sun.cri.ci.CiTargetMethod.*; /** * CiTargetMethod augmented with HotSpot-specific information. @@ -54,21 +54,27 @@ private Site[] getSortedSites(CiTargetMethod target) { List[] lists = new List[] {target.directCalls, target.indirectCalls, target.safepoints, target.dataReferences, target.exceptionHandlers, target.marks}; int count = 0; - for (List list: lists) { + for (List list : lists) { count += list.size(); } Site[] result = new Site[count]; int pos = 0; - for (List list: lists) { - for (Object elem: list) { - result[pos++] = (Site)elem; + for (List list : lists) { + for (Object elem : list) { + result[pos++] = (Site) elem; } } Arrays.sort(result, new Comparator() { + public int compare(Site s1, Site s2) { + if (s1.pcOffset == s2.pcOffset && (s1 instanceof Mark ^ s2 instanceof Mark)) { + return s1 instanceof Mark ? -1 : 1; + } return s1.pcOffset - s2.pcOffset; } }); + for(Site site : result) + System.out.println(site.pcOffset + ": " + site); return result; } diff -r ed6bd46ad55e -r 149b1d2316de c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java Wed Aug 18 11:44:04 2010 -0700 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotXirGenerator.java Wed Aug 18 16:47:06 2010 -0700 @@ -38,8 +38,15 @@ // this needs to correspond to c1x_Compiler.hpp private static final Integer MARK_VERIFIED_ENTRY = 1; private static final Integer MARK_UNVERIFIED_ENTRY = 2; + private static final Integer MARK_OSR_ENTRY = 3; private static final Integer MARK_STATIC_CALL_STUB = 1000; + private static final Integer MARK_INVOKE_INVALID = 2000; + private static final Integer MARK_INVOKEINTERFACE = 2001; + private static final Integer MARK_INVOKESTATIC = 2002; + private static final Integer MARK_INVOKESPECIAL = 2003; + private static final Integer MARK_INVOKEVIRTUAL = 2004; + private final HotSpotVMConfig config; private final CiTarget target; private final RiRegisterConfig registerConfig; @@ -56,6 +63,8 @@ private XirTemplate exceptionObjectTemplate; private XirTemplate invokeStaticTemplate; private XirTemplate invokeSpecialTemplate; + private XirTemplate invokeInterfaceTemplate; + private XirTemplate invokeVirtualTemplate; private XirTemplate newInstanceTemplate; static class XirPair { @@ -122,6 +131,8 @@ instanceofTemplateNonnull = buildInstanceof(true); invokeStaticTemplate = buildInvokeStatic(); invokeSpecialTemplate = buildInvokeSpecial(); + invokeInterfaceTemplate = buildInvokeInterface(); + invokeVirtualTemplate = buildInvokeVirtual(); newInstanceTemplate = buildNewInstance(); return templates; @@ -133,6 +144,7 @@ XirOperand frame_pointer = asm.createRegister("frame pointer", CiKind.Word, AMD64.rbp); asm.align(config.codeEntryAlignment); + asm.mark(MARK_OSR_ENTRY); asm.mark(MARK_UNVERIFIED_ENTRY); if (!staticMethod) { // TODO do some checking... @@ -368,7 +380,8 @@ asm.restart(); XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word); - XirLabel stub = asm.createOutOfLineLabel("staticCallStub"); + XirLabel stub = asm.createOutOfLineLabel("call stub"); + asm.mark(MARK_INVOKESTATIC); asm.bindOutOfLine(stub); XirOperand method = asm.createRegister("method", CiKind.Word, AMD64.rbx); @@ -385,7 +398,8 @@ asm.restart(); XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word); - XirLabel stub = asm.createOutOfLineLabel("specialCallStub"); + XirLabel stub = asm.createOutOfLineLabel("call stub"); + asm.mark(MARK_INVOKESPECIAL); asm.bindOutOfLine(stub); XirOperand method = asm.createRegister("method", CiKind.Word, AMD64.rbx); @@ -398,6 +412,44 @@ return asm.finishTemplate(addr, "invokespecial"); } + private XirTemplate buildInvokeInterface() { + asm.restart(); + XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word); + XirOperand method = asm.createRegister("method", CiKind.Object, AMD64.rbx); + + XirLabel stub = asm.createOutOfLineLabel("call stub"); + asm.mark(MARK_INVOKEINTERFACE); + asm.mov(method, asm.createConstant(CiConstant.forObject(HotSpotProxy.DUMMY_CONSTANT_OBJ))); + + asm.bindOutOfLine(stub); + asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE); + asm.mov(method, asm.w(0l)); + XirLabel dummy = asm.createOutOfLineLabel("dummy"); + asm.jmp(dummy); + asm.bindOutOfLine(dummy); + + return asm.finishTemplate(addr, "invokespecial"); + } + + private XirTemplate buildInvokeVirtual() { + asm.restart(); + XirParameter addr = asm.createConstantInputParameter("addr", CiKind.Word); + XirOperand method = asm.createRegister("method", CiKind.Object, AMD64.rbx); + + XirLabel stub = asm.createOutOfLineLabel("call stub"); + asm.mark(MARK_INVOKEVIRTUAL); + asm.mov(method, asm.createConstant(CiConstant.forObject(HotSpotProxy.DUMMY_CONSTANT_OBJ))); + + asm.bindOutOfLine(stub); + asm.mark(MARK_STATIC_CALL_STUB, XirMark.CALLSITE); + asm.mov(method, asm.w(0l)); + XirLabel dummy = asm.createOutOfLineLabel("dummy"); + asm.jmp(dummy); + asm.bindOutOfLine(dummy); + + return asm.finishTemplate(addr, "invokespecial"); + } + private XirTemplate buildNewInstance() { XirOperand result = asm.restart(CiKind.Word); XirOperand type = asm.createInputParameter("type", CiKind.Object); @@ -515,7 +567,7 @@ @Override public XirSnippet genInvokeInterface(XirSite site, XirArgument receiver, RiMethod method) { - return new XirSnippet(emptyTemplates[CiKind.Word.ordinal()]); + return new XirSnippet(invokeInterfaceTemplate, XirArgument.forWord(0)); } @Override @@ -530,7 +582,7 @@ @Override public XirSnippet genInvokeVirtual(XirSite site, XirArgument receiver, RiMethod method) { - return new XirSnippet(emptyTemplates[CiKind.Word.ordinal()]); + return new XirSnippet(invokeVirtualTemplate, XirArgument.forWord(0)); } @Override diff -r ed6bd46ad55e -r 149b1d2316de src/share/vm/c1x/c1x_Compiler.hpp --- a/src/share/vm/c1x/c1x_Compiler.hpp Wed Aug 18 11:44:04 2010 -0700 +++ b/src/share/vm/c1x/c1x_Compiler.hpp Wed Aug 18 16:47:06 2010 -0700 @@ -60,7 +60,13 @@ enum MarkId { MARK_VERIFIED_ENTRY = 1, MARK_UNVERIFIED_ENTRY = 2, - MARK_STATIC_CALL_STUB = 1000 + MARK_OSR_ENTRY = 3, + MARK_STATIC_CALL_STUB = 1000, + MARK_INVOKE_INVALID = 2000, + MARK_INVOKEINTERFACE = 2001, + MARK_INVOKESTATIC = 2002, + MARK_INVOKESPECIAL = 2003, + MARK_INVOKEVIRTUAL = 2004 }; /* @@ -83,13 +89,14 @@ public: // this enum needs to have the same values as the one in HotSpotProxy.java enum CompilerObjectType { - STUB = 0x100000000000000l, - METHOD = 0x200000000000000l, - CLASS = 0x300000000000000l, - SYMBOL = 0x400000000000000l, - CONSTANT_POOL = 0x500000000000000l, - CONSTANT = 0x600000000000000l, - TYPE_MASK = 0xf00000000000000l + STUB = 0x100000000000000l, + METHOD = 0x200000000000000l, + CLASS = 0x300000000000000l, + SYMBOL = 0x400000000000000l, + CONSTANT_POOL = 0x500000000000000l, + CONSTANT = 0x600000000000000l, + TYPE_MASK = 0xf00000000000000l, + DUMMY_CONSTANT = 0x6ffffffffffffffl }; static void initializeObjects(); diff -r ed6bd46ad55e -r 149b1d2316de src/share/vm/c1x/c1x_VMEntries.cpp --- a/src/share/vm/c1x/c1x_VMEntries.cpp Wed Aug 18 11:44:04 2010 -0700 +++ b/src/share/vm/c1x/c1x_VMEntries.cpp Wed Aug 18 16:47:06 2010 -0700 @@ -322,9 +322,6 @@ arrayOop register_map = (arrayOop)CiDebugInfo::registerRefMap(debug_info); arrayOop frame_map = (arrayOop)CiDebugInfo::frameRefMap(debug_info); - jint register_count = VMRegImpl::stack2reg(0)->value(); - tty->print_cr("register count: %i", register_count); - for (jint i=0; ibase(T_BYTE))[i / 8]; bool is_oop = (byte & (1 << (i % 8))) != 0; @@ -382,6 +379,9 @@ jint _constants_size; jint _total_size; + C1XCompiler::MarkId _next_call_type; + address _invoke_mark_pc; + CodeSection* _instructions; CodeSection* _constants; @@ -451,6 +451,8 @@ // (very) conservative estimate: each site needs a constant section entry _constants_size = _sites->length() * BytesPerLong; _total_size = align_size_up(_code_size, HeapWordSize) + _constants_size; + + _next_call_type = C1XCompiler::MARK_INVOKE_INVALID; } void site_Safepoint(CodeBuffer& buffer, jint pc_offset, oop site) { @@ -556,28 +558,47 @@ oop frame = CiDebugInfo::frame(debug_info); record_frame(next_pc_offset, code_pos, frame); - if (method->is_static()) { - tty->print_cr("static method"); + switch(_next_call_type) { + case C1XCompiler::MARK_INVOKEVIRTUAL: + case C1XCompiler::MARK_INVOKEINTERFACE: { + assert(!method->is_static(), "cannot call static method with invokeinterface"); + + address dest = SharedRuntime::get_resolve_virtual_call_stub(); + long disp = dest - next_instruction; + assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); + *((jint*)operand) = (jint)disp; - address dest = SharedRuntime::get_resolve_static_call_stub(); - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*)operand) = (jint)disp; + _instructions->relocate(instruction, virtual_call_Relocation::spec(_invoke_mark_pc), Assembler::call32_operand); + break; + } + case C1XCompiler::MARK_INVOKESTATIC: { + assert(method->is_static(), "cannot call non-static method with invokestatic"); + + address dest = SharedRuntime::get_resolve_static_call_stub(); + long disp = dest - next_instruction; + assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); + *((jint*)operand) = (jint)disp; - _instructions->relocate(instruction, relocInfo::static_call_type, Assembler::call32_operand); - tty->print_cr("relocating (Long) %016x/%016x", instruction, operand); - } else { - tty->print_cr("non-static method"); + _instructions->relocate(instruction, relocInfo::static_call_type, Assembler::call32_operand); + break; + } + case C1XCompiler::MARK_INVOKESPECIAL: { + assert(!method->is_static(), "cannot call static method with invokespecial"); - address dest = SharedRuntime::get_resolve_opt_virtual_call_stub(); - long disp = dest - next_instruction; - assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); - *((jint*)operand) = (jint)disp; + address dest = SharedRuntime::get_resolve_opt_virtual_call_stub(); + long disp = dest - next_instruction; + assert(disp == (jint) disp, "disp doesn't fit in 32 bits"); + *((jint*)operand) = (jint)disp; - _instructions->relocate(instruction, relocInfo::opt_virtual_call_type, Assembler::call32_operand); - tty->print_cr("relocating (Long) %016x/%016x", instruction, operand); + _instructions->relocate(instruction, relocInfo::opt_virtual_call_type, Assembler::call32_operand); + break; + } + case C1XCompiler::MARK_INVOKE_INVALID: + default: + ShouldNotReachHere(); + break; } - + _next_call_type = C1XCompiler::MARK_INVOKE_INVALID; _debug_recorder->end_safepoint(pc_offset); } } @@ -630,35 +651,14 @@ address operand = Assembler::locate_operand(instruction, Assembler::imm_operand); - *((jobject*)operand) = JNIHandles::make_local(C1XObjects::get(id)); + if (id == C1XObjects::DUMMY_CONSTANT) { + *((jobject*)operand) = (jobject)Universe::non_oop_word(); + } else { + *((jobject*)operand) = JNIHandles::make_local(C1XObjects::get(id)); + } _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); tty->print_cr("relocating (oop constant) at %016x/%016x", instruction, operand); } - - /* - jlong id = com_sun_hotspot_c1x_HotSpotProxy::get_id(obj); - switch (id & C1XObjects::TYPE_MASK) { - case C1XObjects::CONSTANT: { - address operand = Assembler::locate_operand(inst, Assembler::imm_operand); - - *((jobject*)operand) = JNIHandles::make_local(C1XObjects::get(id)); - instructions->relocate(inst, oop_Relocation::spec_for_immediate(), Assembler::imm_operand); - tty->print_cr("relocating (HotSpotType) %02x at %016x/%016x", inst_byte, inst, operand); - break; - } - case C1XObjects::STUB: { - address operand = Assembler::locate_operand(inst, Assembler::call32_operand); - - long dest = (long)C1XObjects::getStub(id); - long disp = dest - (long)(operand + 4); - assert(disp == (int) disp, "disp doesn't fit in 32 bits"); - *((int*)operand) = (int)disp; - - instructions->relocate(inst, runtime_call_Relocation::spec(), Assembler::call32_operand); - tty->print_cr("relocating (Long) %02x at %016x/%016x", inst_byte, inst, operand); - break; - } - }*/ break; } default: @@ -688,6 +688,9 @@ case C1XCompiler::MARK_VERIFIED_ENTRY: _offsets.set_value(CodeOffsets::Verified_Entry, pc_offset); break; + case C1XCompiler::MARK_OSR_ENTRY: + _offsets.set_value(CodeOffsets::OSR_Entry, pc_offset); + break; case C1XCompiler::MARK_STATIC_CALL_STUB: { assert(references->length() == 1, "static call stub needs one reference"); oop ref = ((oop*)references->base(T_OBJECT))[0]; @@ -695,6 +698,17 @@ _instructions->relocate(instruction, static_stub_Relocation::spec(call_pc)); break; } + case C1XCompiler::MARK_INVOKE_INVALID: + case C1XCompiler::MARK_INVOKEINTERFACE: + case C1XCompiler::MARK_INVOKESTATIC: + case C1XCompiler::MARK_INVOKESPECIAL: + case C1XCompiler::MARK_INVOKEVIRTUAL: + _next_call_type = (C1XCompiler::MarkId)id; + _invoke_mark_pc = instruction; + break; + default: + ShouldNotReachHere(); + break; } } }