Index: vm/gc_gen/javasrc/org/apache/harmony/drlvm/gc_gen/GCHelper.java =================================================================== --- vm/gc_gen/javasrc/org/apache/harmony/drlvm/gc_gen/GCHelper.java (revision 596581) +++ vm/gc_gen/javasrc/org/apache/harmony/drlvm/gc_gen/GCHelper.java (working copy) @@ -32,7 +32,11 @@ } public static final int TLS_GC_OFFSET = TLSGCOffset(); + public static final int PREFETCH_DISTANCE = getPrefetchDist(); + public static final int ZEROING_SIZE = getZeroingSize(); + public static final int PREFETCH_STRIDE = getPrefetchStride(); + @Inline public static Address alloc(int objSize, int allocationHandle) { Address TLS_BASE = VMHelper.getTlsBaseAddress(); @@ -41,15 +45,34 @@ Address allocator = allocator_addr.loadAddress(); Address free_addr = allocator.plus(0); Address free = free_addr.loadAddress(); - Address ceiling = allocator.plus(4).loadAddress(); - + Address ceiling_addr = allocator.plus(4); + Address ceiling = ceiling_addr.loadAddress(); + Address new_free = free.plus(objSize); if (new_free.LE(ceiling)) { free_addr.store(new_free); free.store(allocationHandle); return free; - } + } else { + Address end = allocator.plus(8).loadAddress(); + if(new_free.LE(end)) { + // do prefetch from new_free to new_free + PREFETCH_DISTANCE + ZEROING_SIZE + VMHelper.prefetch(new_free, PREFETCH_DISTANCE + ZEROING_SIZE, PREFETCH_STRIDE); + + Address new_ceiling = new_free.plus(ZEROING_SIZE); + if( !new_ceiling.LE(end) ){ + new_ceiling = end; + } + + VMHelper.memset0(ceiling , new_ceiling.diff(ceiling).toInt()); + + ceiling_addr.store(new_ceiling); + free_addr.store(new_free); + free.store(allocationHandle); + return free; + } + } return VMHelper.newResolvedUsingAllocHandleAndSize(objSize, allocationHandle); } @@ -91,9 +114,13 @@ VMHelper.writeBarrier(p_objBase, p_objSlot, p_target); } + private static native int getPrefetchDist(); + private static native int getZeroingSize(); + private static native int getPrefetchStride(); private static native int helperCallback(); private static native boolean getGenMode(); private static native long getNosBoundary(); private static native int TLSGCOffset(); } + Index: vm/gc_gen/src/jni/java_natives.cpp =================================================================== --- vm/gc_gen/src/jni/java_natives.cpp (revision 596581) +++ vm/gc_gen/src/jni/java_natives.cpp (working copy) @@ -37,6 +37,21 @@ return (jint)tls_gc_offset; } +JNIEXPORT jint JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getPrefetchDist(JNIEnv *e, jclass c) +{ + return (jint)PREFETCH_DISTANCE; +} + +JNIEXPORT jint JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getZeroingSize(JNIEnv *e, jclass c) +{ + return (jint)ZEROING_SIZE; +} + +JNIEXPORT jint JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getPrefetchStride(JNIEnv *e, jclass c) +{ + return (jint)PREFETCH_STRIDE; +} + JNIEXPORT jlong JNICALL Java_org_apache_harmony_drlvm_gc_1gen_GCHelper_getNosBoundary(JNIEnv *e, jclass c) { return (jlong)nos_boundary; Index: vm/jitrino/src/codegenerator/CodeGenIntfc.h =================================================================== --- vm/jitrino/src/codegenerator/CodeGenIntfc.h (revision 596581) +++ vm/jitrino/src/codegenerator/CodeGenIntfc.h (working copy) @@ -164,6 +164,8 @@ class JitHelperCallOp { public: enum Id { + Prefetch, + Memset0, InitializeArray, FillArrayWithConst, SaveThisState, Index: vm/jitrino/src/codegenerator/ia32/Ia32Inst.h =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32Inst.h (revision 596581) +++ vm/jitrino/src/codegenerator/ia32/Ia32Inst.h (working copy) @@ -749,12 +749,14 @@ if(m==Mnemonic_MOVS8 || m==Mnemonic_MOVS16 || m==Mnemonic_MOVS32 || + m==Mnemonic_STOS || m==Mnemonic_STD || m==Mnemonic_CLD || m==Mnemonic_POPFD || m==Mnemonic_PUSHFD || m==Mnemonic_POP || - m==Mnemonic_PUSH ) + m==Mnemonic_PUSH || + m==Mnemonic_PREFETCH ) { return true; } Index: vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp =================================================================== --- vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (revision 596581) +++ vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (working copy) @@ -2607,6 +2607,58 @@ { Opnd * dstOpnd=createResultOpnd(retType); switch(callId) { + case Prefetch: + { + assert (numArgs == 3); + Opnd* address = (Opnd*) args[0]; + Opnd* distance = (Opnd*) args[1]; + Opnd* stride = (Opnd*) args[2]; + + assert (distance->isPlacedIn(OpndKind_Imm) && stride->isPlacedIn(OpndKind_Imm)); + int dist = distance->getImmValue(); + int strd = stride->getImmValue(); + + for (int i=0; i< dist; i+=strd) + { + Opnd* prefAddress = irManager.newMemOpnd(typeManager.getInt8Type(), address, 0, 0, irManager.newImmOpnd(typeManager.getInt32Type(), i)); + Inst* inst = irManager.newInst(Mnemonic_PREFETCH, prefAddress); + appendInsts(inst); + } + break; + } + + case Memset0: + { + assert(numArgs == 2); + Opnd** opnds = (Opnd**)args; + Opnd *addr = opnds[0]; + Opnd *size = opnds[1]; + + RegName counterRegName = RegName_ECX; + RegName dstRegName = RegName_EDI; + RegName zeroRegName = RegName_EAX; + + // prepare counter + Type* int32Type = typeManager.getInt32Type(); + Opnd* counter = irManager.newRegOpnd(int32Type,counterRegName); + copyOpnd(counter,size); + appendInsts(irManager.newInst(Mnemonic_SHR, counter, irManager.newImmOpnd(int32Type,2))); + + // prepare dst + Opnd* dst = irManager.newRegOpnd(int32Type,dstRegName); + copyOpnd(dst, addr); + + // prepare zero + Opnd* eax = irManager.newRegOpnd(int32Type,zeroRegName); + //appendInsts(irManager.newInst(Mnemonic_XOR, eax, eax)); + Opnd* zero = irManager.newImmOpnd(int32Type,0); + appendInsts(irManager.newInst(Mnemonic_MOV, eax, zero)); + + Inst* storeInst = irManager.newInst(Mnemonic_STOS, dst, counter, eax); + storeInst->setPrefix(InstPrefix_REP); + appendInsts(storeInst); + break; + } case InitializeArray: assert(numArgs == 4); appendInsts(irManager.newInternalRuntimeHelperCallInst("initialize_array", numArgs, (Opnd**)args, dstOpnd)); Index: vm/jitrino/src/optimizer/CodeSelectors.cpp =================================================================== --- vm/jitrino/src/optimizer/CodeSelectors.cpp (revision 596581) +++ vm/jitrino/src/optimizer/CodeSelectors.cpp (working copy) @@ -403,6 +403,8 @@ JitHelperCallOp::Id _BlockCodeSelector::convertJitHelperId(JitHelperCallId callId) { switch(callId) { + case Prefetch: return JitHelperCallOp::Prefetch; + case Memset0: return JitHelperCallOp::Memset0; case InitializeArray: return JitHelperCallOp::InitializeArray; case SaveThisState: return JitHelperCallOp::SaveThisState; case ReadThisState: return JitHelperCallOp::ReadThisState; Index: vm/jitrino/src/optimizer/escanalyzer.cpp =================================================================== --- vm/jitrino/src/optimizer/escanalyzer.cpp (revision 596581) +++ vm/jitrino/src/optimizer/escanalyzer.cpp (working copy) @@ -407,6 +407,8 @@ case Op_JitHelperCall: // calljithelper if (method_ea_level == 0) { switch(inst->asJitHelperCallInst()->getJitHelperId()) { + case Prefetch: + case Memset0: case InitializeArray: case FillArrayWithConst: case SaveThisState: @@ -606,7 +608,7 @@ case Op_TauVirtualCall: // callvirt case Op_IndirectCall: // calli - + case Op_TauStRef: case Op_TauStField: case Op_TauStElem: @@ -5871,3 +5873,4 @@ } //namespace Jitrino + Index: vm/jitrino/src/optimizer/Inst.cpp =================================================================== --- vm/jitrino/src/optimizer/Inst.cpp (revision 596581) +++ vm/jitrino/src/optimizer/Inst.cpp (working copy) @@ -464,6 +464,10 @@ switch(code) { case 'd': switch(jitHelperId) { + case Prefetch: + os << "Prefetch"; break; + case Memset0: + os << "Memset0"; break; case InitializeArray: os << "InitializeArray"; break; case SaveThisState: Index: vm/jitrino/src/optimizer/memoryopt.cpp =================================================================== --- vm/jitrino/src/optimizer/memoryopt.cpp (revision 596581) +++ vm/jitrino/src/optimizer/memoryopt.cpp (working copy) @@ -661,6 +661,8 @@ JitHelperCallInst *jitcalli = i->asJitHelperCallInst(); JitHelperCallId callId = jitcalli->getJitHelperId(); switch (callId) { + case Prefetch: + case Memset0: case InitializeArray: case SaveThisState: case ReadThisState: Index: vm/jitrino/src/optimizer/Opcode.h =================================================================== --- vm/jitrino/src/optimizer/Opcode.h (revision 596581) +++ vm/jitrino/src/optimizer/Opcode.h (working copy) @@ -270,6 +270,8 @@ }; enum JitHelperCallId { + Prefetch, + Memset0, InitializeArray, FillArrayWithConst, SaveThisState, //todo: replace with GetTLS + offset sequence Index: vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp =================================================================== --- vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp (revision 596581) +++ vm/jitrino/src/translator/java/JavaByteCodeTranslator.cpp (working copy) @@ -3577,6 +3577,20 @@ return true; } + if (!strcmp(mname, "memset0")) + { + assert(numArgs == 2); + irBuilder.genJitHelperCall(Memset0, resType, numArgs, srcOpnds); + return true; + } + + if (!strcmp(mname, "prefetch")) + { + assert(numArgs == 3); + irBuilder.genJitHelperCall(Prefetch, resType, numArgs, srcOpnds); + return true; + } + if (!strcmp(mname,"getInterfaceVTable")) { assert(numArgs == 2); Opnd* res = irBuilder.genVMHelperCall(VM_RT_GET_INTERFACE_VTABLE_VER0, resType, numArgs, srcOpnds); Index: vm/port/src/encoder/ia32_em64t/enc_defs.h =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_defs.h (revision 596581) +++ vm/port/src/encoder/ia32_em64t/enc_defs.h (working copy) @@ -550,6 +550,7 @@ Mnemonic_NOP, // No Operation Mnemonic_NOT, // One's Complement Negation Mnemonic_OR, // Logical Inclusive OR +Mnemonic_PREFETCH, // prefetch #ifdef _HAVE_MMX_ Mnemonic_PADDQ, // Add Packed Quadword Integers Index: vm/port/src/encoder/ia32_em64t/enc_tabl.cpp =================================================================== --- vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (revision 596581) +++ vm/port/src/encoder/ia32_em64t/enc_tabl.cpp (working copy) @@ -1144,6 +1144,12 @@ END_OPCODES() END_MNEMONIC() +BEGIN_MNEMONIC(PREFETCH, MF_NONE, U) +BEGIN_OPCODES() +{OpcodeInfo::all, {0x0F, 0x18, _0}, {m8}, U }, +END_OPCODES() +END_MNEMONIC() + BEGIN_MNEMONIC(NOT, MF_AFFECTS_FLAGS, DU ) BEGIN_OPCODES() {OpcodeInfo::all, {0xF6, _2}, {r_m8}, DU }, @@ -1409,6 +1415,13 @@ END_OPCODES() END_MNEMONIC() +BEGIN_MNEMONIC(STOS, MF_AFFECTS_FLAGS, DU_DU_U) +BEGIN_OPCODES() + {OpcodeInfo::all, {0xAB}, {EDI, ECX, EAX}, DU_DU_U }, + {OpcodeInfo::em64t, {REX_W, 0xAB}, {RDI, RCX, RAX}, DU_DU_U }, +END_OPCODES() +END_MNEMONIC() + /* MOVS and CMPS are the special cases. Most the code in both CG and Encoder do not expect 2 memory operands. Index: vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java =================================================================== --- vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java (revision 596581) +++ vm/vmcore/src/kernel_classes/javasrc/org/apache/harmony/drlvm/VMHelper.java (working copy) @@ -47,6 +47,10 @@ public static void monitorExit(Object obj) {fail();} + public static void memset0(Address addr, int size) {fail();} + + public static void prefetch(Address addr, int distance, int stride) {fail();} + public static void writeBarrier(Address objBase, Address objSlot, Address source) {fail();} public static Address getInterfaceVTable(Object obj, Address intfTypePtr) {fail(); return null;}