From 56cfa9c73c96c9a110eacf9676b2d55389843db2 Mon Sep 17 00:00:00 2001 From: ottoni Date: Wed, 20 Mar 2013 19:17:18 -0700 Subject: [PATCH] Eliminate IncRef/DecRef pair when a method returns $this Instead of generating IR like: t1:Obj = LdThis t0:StkPtr t2:Obj = IncRef t1:Obj ... DecRef t1:Obj RetVal t2:Obj ... This diff changes HhbcTranslator to produce: t1:Obj = LdThis t0:StkPtr t2:Obj = IncRef t1:Obj ... DecRefNZ t2:Obj RetVal t1:Obj ... This enables the ref-counting optimization to kick in. --- .../vm/translator/hopt/hhbctranslator.cpp | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp b/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp index aaf6e7057..17f4f8415 100644 --- a/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp +++ b/hphp/runtime/vm/translator/hopt/hhbctranslator.cpp @@ -1629,9 +1629,6 @@ void HhbcTranslator::emitRet(Type type, bool freeInline) { m_tb->genReleaseVVOrExit(getExitSlowTrace()); } SSATmp* retVal = pop(type); - if (mayHaveThis) { - m_tb->genDecRefThis(); - } SSATmp* sp; if (freeInline) { @@ -1642,14 +1639,26 @@ void HhbcTranslator::emitRet(Type type, bool freeInline) { * IncRef/DecRef pair in the main trace. */ SSATmp* retValSrcLoc = nullptr; + Opcode retValSrcOpc = Nop; // Nop flags the ref-count opti is impossible IRInstruction* retValSrcInstr = retVal->getInstruction(); if (retValSrcInstr->getOpcode() == IncRef) { retValSrcLoc = retValSrcInstr->getSrc(0); - if (retValSrcLoc->getInstruction()->getOpcode() != LdLoc) { + retValSrcOpc = retValSrcLoc->getInstruction()->getOpcode(); + if (retValSrcOpc != LdLoc && retValSrcOpc != LdThis) { retValSrcLoc = nullptr; + retValSrcOpc = Nop; } } - int retValLocId = retValSrcLoc ? + + if (mayHaveThis) { + if (retValSrcLoc && retValSrcOpc == LdThis) { + m_tb->genDecRef(retVal); + } else { + m_tb->genDecRefThis(); + } + } + + int retValLocId = (retValSrcLoc && retValSrcOpc == LdLoc) ? retValSrcLoc->getInstruction()->getExtra()->locId : -1; for (int id = curFunc->numLocals() - 1; id >= 0; --id) { /* @@ -1665,6 +1674,9 @@ void HhbcTranslator::emitRet(Type type, bool freeInline) { m_tb->genRetVal(retValSrcLoc ? retValSrcLoc : retVal); sp = m_tb->genRetAdjustStack(); } else { + if (mayHaveThis) { + m_tb->genDecRefThis(); + } sp = m_tb->genGenericRetDecRefs(retVal, curFunc->numLocals()); m_tb->genRetVal(retVal); }