in vm/jitrino/src/codegenerator/ia32/Ia32APIMagics.cpp [113:238]
void APIMagicsHandlerSession::runImpl() {
CompilationContext* cc = getCompilationContext();
MemoryManager tmpMM("Inline API methods");
#ifndef _EM64T_
bool mathAsMagic = getBoolArg("magic_math", true);
#endif
//finding all api magic calls
IRManager* irm = cc->getLIRManager();
ControlFlowGraph* fg = irm->getFlowGraph();
StlVector<APIMagicHandler*> handlers(tmpMM);
const Nodes& nodes = fg->getNodesPostOrder();//process checking only reachable nodes.
for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) {
Node* node = *it;
if (node->isBlockNode()) {
for (Inst* inst = (Inst*)node->getFirstInst(); inst!=NULL; inst = inst->getNextInst()) {
if (!inst->hasKind(Inst::Kind_CallInst)) {
continue;
}
if ( ((CallInst*)inst)->isDirect() ) {
CallInst* callInst = (CallInst*)inst;
Opnd * targetOpnd=callInst->getOpnd(callInst->getTargetOpndIndex());
assert(targetOpnd->isPlacedIn(OpndKind_Imm));
Opnd::RuntimeInfo * ri=targetOpnd->getRuntimeInfo();
if( !ri ) {
continue;
};
if( ri->getKind() == Opnd::RuntimeInfo::Kind_MethodDirectAddr ){
#ifndef _EM64T_
MethodDesc * md = (MethodDesc*)ri->getValue(0);
const char* className = md->getParentType()->getName();
const char* methodName = md->getName();
const char* signature = md->getSignatureString();
if (!strcmp(className, "java/lang/Integer")) {
if (!strcmp(methodName, "numberOfLeadingZeros") && !strcmp(signature, "(I)I")) {
handlers.push_back(new (tmpMM) Integer_numberOfLeadingZeros_Handler_x_I_x_I(irm, callInst, md));
} else if (!strcmp(methodName, "numberOfTrailingZeros") && !strcmp(signature, "(I)I")) {
handlers.push_back(new (tmpMM) Integer_numberOfTrailingZeros_Handler_x_I_x_I(irm, callInst, md));
}
} else if (!strcmp(className, "java/lang/Long")) {
if (!strcmp(methodName, "numberOfLeadingZeros") && !strcmp(signature, "(J)I")) {
handlers.push_back(new (tmpMM) Long_numberOfLeadingZeros_Handler_x_J_x_I(irm, callInst, md));
} else if (!strcmp(methodName, "numberOfTrailingZeros") && !strcmp(signature, "(J)I")) {
handlers.push_back(new (tmpMM) Long_numberOfTrailingZeros_Handler_x_J_x_I(irm, callInst, md));
}
} else if (!strcmp(className, "java/lang/Float")) {
if (!strcmp(methodName, "floatToRawIntBits") && !strcmp(signature, "(F)I")) {
handlers.push_back(new (tmpMM) Float_floatToRawIntBits_x_F_x_I(irm, callInst, md));
} else if (!strcmp(methodName, "intBitsToFloat") && !strcmp(signature, "(I)F")) {
handlers.push_back(new (tmpMM) Float_intBitsToFloat_x_I_x_F(irm, callInst, md));
}
} else if (mathAsMagic && !strcmp(className, "java/lang/Math")) {
if (!strcmp(signature, "(D)D")) {
if (!strcmp(methodName, "sqrt")) {
handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, SQRT, Mnemonic_FSQRT));
}
if (!strcmp(methodName, "sin")) {
handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, SIN, Mnemonic_FSIN));
}
if (!strcmp(methodName, "cos")) {
handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, COS, Mnemonic_FCOS));
}
if (!strcmp(methodName, "abs")) {
handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, ABS, Mnemonic_FABS));
}
if (!strcmp(methodName, "tan")) {
handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, TAN, Mnemonic_FPTAN));
}
if (!strcmp(methodName, "log")) {
handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, LOG, Mnemonic_FLDLN2));
}
if (!strcmp(methodName, "log10")) {
handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, LOG10, Mnemonic_FLDLG2));
}
if (!strcmp(methodName, "log1p")) {
handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, LOG1P, Mnemonic_FLDLN2));
}
if (!strcmp(methodName, "atan")) {
handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, ATAN));
}
if (!strcmp(methodName, "asin")) {
handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, ASIN));
}
if (!strcmp(methodName, "acos")) {
handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, ACOS));
}
} else if (!strcmp(signature, "(F)F") && !strcmp(methodName, "abs")) {
handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, ABS, Mnemonic_FABS));
} else if (!strcmp(signature, "(DD)D") && !strcmp(methodName, "atan2")) {
handlers.push_back(new (tmpMM) Math_Handler_x_D_x_D(irm, callInst, md, ATAN2));
}
}
#endif
} else if( ri->getKind() == Opnd::RuntimeInfo::Kind_InternalHelperAddress ) {
if( strcmp((char*)ri->getValue(0),"memory_copy_direct")==0 ) {
if(getBoolArg("System_arraycopy_as_magic", true)) {
handlers.push_back(new (tmpMM) System_arraycopyDirect_Handler(irm, callInst, NULL));
} else { assert(0); }
} else if( strcmp((char*)ri->getValue(0),"memory_copy_reverse")==0 ) {
if(getBoolArg("System_arraycopy_as_magic", true)) {
handlers.push_back(new (tmpMM) System_arraycopyReverse_Handler(irm, callInst, NULL));
} else { assert(0); }
} else if( strcmp((char*)ri->getValue(0),"String_compareTo")==0 ) {
if(getBoolArg("String_compareTo_as_magic", true))
handlers.push_back(new (tmpMM) String_compareTo_Handler_x_String_x_I(irm, callInst, NULL));
} else if( strcmp((char*)ri->getValue(0),"String_regionMatches")==0 ) {
if(getBoolArg("String_regionMatches_as_magic", true))
handlers.push_back(new (tmpMM) String_regionMatches_Handler_x_I_x_String_x_I_x_I_x_Z(irm, callInst, NULL));
} else if( strcmp((char*)ri->getValue(0),"String_indexOf")==0 ) {
if(getBoolArg("String_indexOf_as_magic", true))
handlers.push_back(new (tmpMM) String_indexOf_Handler_x_String_x_I_x_I(irm, callInst, NULL));
}
}
}
}
}
}
//running all handlers
for (StlVector<APIMagicHandler*>::const_iterator it = handlers.begin(), end = handlers.end(); it!=end; ++it) {
APIMagicHandler* handler = *it;
handler->run();
}
if (handlers.size() > 0) {
irm->invalidateLivenessInfo();
}
}