You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by va...@apache.org on 2007/03/05 07:52:41 UTC
svn commit: r514575 -
/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp
Author: varlax
Date: Sun Mar 4 22:52:40 2007
New Revision: 514575
URL: http://svn.apache.org/viewvc?view=rev&rev=514575
Log:
Applied HARMONY-3189 [drlvm][jit][opt] code patching works incorrectly on EM64T
Modified:
harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp
Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp?view=diff&rev=514575&r1=514574&r2=514575
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/codegenerator/ia32/Ia32CodeEmitter.cpp Sun Mar 4 22:52:40 2007
@@ -492,64 +492,75 @@
bool isBcRequired = irManager->getCompilationInterface().isBCMapInfoRequired();
BcMap* bcMap = new(irmm) BcMap(irmm);
irManager->setInfo("bcMap", bcMap);
+ bool newOpndsCreated = false;
for( BasicBlock * bb = (BasicBlock*)irManager->getFlowGraph()->getEntryNode(); bb != NULL; bb=bb->getLayoutSucc()) {
- uint64 bcOffset;
for (Inst* inst = (Inst*)bb->getFirstInst(); inst!=NULL; inst = inst->getNextInst()) {
- if (inst->hasKind(Inst::Kind_ControlTransferInst) &&
- ((ControlTransferInst*)inst)->isDirect()
- ){
- uint8 * instCodeStartAddr=(uint8*)inst->getCodeStartAddr();
- uint8 * instCodeEndAddr=(uint8*)instCodeStartAddr+inst->getCodeSize();
- uint8 * targetCodeStartAddr=0;
- uint32 targetOpndIndex = ((ControlTransferInst*)inst)->getTargetOpndIndex();
- if (inst->hasKind(Inst::Kind_BranchInst)){
- BasicBlock * bbTarget=(BasicBlock*)((BranchInst*)inst)->getTrueTarget();
- targetCodeStartAddr=(uint8*)bbTarget->getCodeStartAddr();
- } else if (inst->hasKind(Inst::Kind_JmpInst)){
- BasicBlock* bbTarget = (BasicBlock*)bb->getUnconditionalEdgeTarget();
- targetCodeStartAddr=(uint8*)bbTarget->getCodeStartAddr();
- } else if (inst->hasKind(Inst::Kind_CallInst)){
- targetCodeStartAddr=(uint8*)(POINTER_SIZE_INT)inst->getOpnd(targetOpndIndex)->getImmValue();
- }else
- continue;
- int64 offset=targetCodeStartAddr-instCodeEndAddr;
+ if (inst->hasKind(Inst::Kind_ControlTransferInst) &&
+ ((ControlTransferInst*)inst)->isDirect()
+ ){
+ uint8 * instCodeStartAddr=(uint8*)inst->getCodeStartAddr();
+ uint8 * instCodeEndAddr=(uint8*)instCodeStartAddr+inst->getCodeSize();
+ uint8 * targetCodeStartAddr=0;
+ uint32 targetOpndIndex = ((ControlTransferInst*)inst)->getTargetOpndIndex();
+ if (inst->hasKind(Inst::Kind_BranchInst)){
+ BasicBlock * bbTarget=(BasicBlock*)((BranchInst*)inst)->getTrueTarget();
+ targetCodeStartAddr=(uint8*)bbTarget->getCodeStartAddr();
+ } else if (inst->hasKind(Inst::Kind_JmpInst)){
+ BasicBlock* bbTarget = (BasicBlock*)bb->getUnconditionalEdgeTarget();
+ targetCodeStartAddr=(uint8*)bbTarget->getCodeStartAddr();
+ } else if (inst->hasKind(Inst::Kind_CallInst)){
+ targetCodeStartAddr=(uint8*)(POINTER_SIZE_INT)inst->getOpnd(targetOpndIndex)->getImmValue();
+ }else
+ continue;
+ int64 offset=targetCodeStartAddr-instCodeEndAddr;
+ uint64 bcOffset = isBcRequired ? bc2LIRMapHandler->getVectorEntry(inst->getId()) : ILLEGAL_VALUE;
#ifdef _EM64T_
- if (!fit32(offset)) { // offset as a signed value does not fits into 32 bits
- const RegName TMP_BASE = RegName_R14;
- EncoderBase::Operands args;
- args.clear();
- args.add(TMP_BASE);
- args.add(EncoderBase::Operand(OpndSize_64, offset));
- char * ip = EncoderBase::encode((char*)instCodeStartAddr, Mnemonic_MOV, args);
- args.clear();
- args.add(TMP_BASE);
- EncoderBase::encode(ip, Mnemonic_CALL, args);
- } else {
+ if ( !fit32(offset) ) { // offset is not a signed value that fits into 32 bits
+ Type* targetType = irManager->getTypeManager().getInt64Type();
+
+ Opnd* targetVal = irManager->newImmOpnd(targetType,(int64)targetCodeStartAddr);
+ Opnd* targetReg = irManager->newRegOpnd(targetType, RegName_R14);
+
+ Inst* movInst = irManager->newInst(Mnemonic_MOV, targetReg, targetVal);
+
+ inst->setOpnd(targetOpndIndex,targetReg);
+
+ bb->prependInst(movInst,inst);
+
+ uint8* blockStartIp = (uint8*)bb->getCodeStartAddr();
+ uint8* ip = movInst->emit(instCodeStartAddr);
+ movInst->setCodeOffset(instCodeStartAddr - blockStartIp);
+ inst->emit(ip);
+ inst->setCodeOffset(ip - blockStartIp);
+
+ if (bcOffset != ILLEGAL_VALUE) {
+ bcMap->setEntry((uint64)(POINTER_SIZE_INT)instCodeStartAddr, bcOffset); // MOV
+ bcMap->setEntry((uint64)(POINTER_SIZE_INT)ip, bcOffset); // CALL
+ }
+
+ newOpndsCreated = true;
+ }
+ else
#endif
- inst->getOpnd(targetOpndIndex)->assignImmValue((int64)offset);
+ {
+ inst->getOpnd(targetOpndIndex)->assignImmValue(offset);
// re-emit the instruction:
inst->emit(instCodeStartAddr);
if (inst->hasKind(Inst::Kind_CallInst)){
registerDirectCall(inst);
}
-#ifdef _EM64T_
- }
-#endif
- }
- // todo64
- if (isBcRequired) {
- uint64 instID = inst->getId();
- bcOffset = bc2LIRMapHandler->getVectorEntry(instID);
-
- if (bcOffset != ILLEGAL_VALUE) {
- POINTER_SIZE_INT instStartAddr = (POINTER_SIZE_INT) inst->getCodeStartAddr();
- bcMap->setEntry((uint64) instStartAddr, bcOffset);
- }
+
+ if (bcOffset != ILLEGAL_VALUE) {
+ bcMap->setEntry((uint64)(POINTER_SIZE_INT)instCodeStartAddr, bcOffset);
}
+ }
+ }
}
- }
+ }
+ if (newOpndsCreated)
+ irManager->fixLivenessInfo();
}
//________________________________________________________________________________________
@@ -579,15 +590,25 @@
Byte ** indirectAddr = (Byte **)recompiledMethodDesc->getIndirectAddress();
Byte * targetAddr = *indirectAddr;
Byte * callAddr = (Byte*)data;
- assert(fit32(targetAddr - callAddr-5));
- uint32 offset = (uint32)(targetAddr - callAddr-5);
-
- //FIXME
- //if (Log::cat_rt()->isDebugEnabled()) {
- // Log::cat_rt()->out() << "patching call to "<<recompiledMethodDesc->getName()<<" at "<<(void*)callAddr<<"; new target address is "<<(void*)targetAddr<< ::std::endl;
- //}
- *(uint32*)(callAddr+1)=offset;
+ uint64 offset = targetAddr - callAddr-5;
+
+#ifdef _EM64T_
+ if ( !fit32(offset) ) { // offset is not a signed value that fits into 32 bits
+ EncoderBase::Operands args;
+ args.clear();
+ args.add(RegName_R14);
+ // direct call <imm> is relative, but call <reg> use an absolute address to jump
+ args.add(EncoderBase::Operand(OpndSize_64, (int64)targetAddr));
+ char * ip = EncoderBase::encode((char*)callAddr, Mnemonic_MOV, args);
+ args.clear();
+ args.add(RegName_R14);
+ EncoderBase::encode(ip, Mnemonic_CALL, args);
+ } else
+#endif
+ { // offset fits into 32 bits
+ *(uint32*)(callAddr+1) = (uint32)offset;
+ }
return true;
}
@@ -891,5 +912,6 @@
}}; // ~Jitrino::Ia32
+