CreateCont opcode optimization - avoid unnecessary reference counting.

Continuation argument values are copied to the continuation object and the locals are unset - in this way we don't need to change the reference coutners.
Esse commit está contido em:
Mirek Klimos
2013-06-21 18:54:28 -07:00
commit de Sara Golemon
commit 56ddbc6bd3
3 arquivos alterados com 20 adições e 9 exclusões
+11 -5
Ver Arquivo
@@ -14,14 +14,14 @@
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_TV_HELPERS_H_
#define incl_HPHP_TV_HELPERS_H_
#ifndef incl_HPHP_INSIDE_HPHP_COMPLEX_TYPES_H_
#error Directly including 'tv_helpers.h' is prohibited. \
Include 'complex_types.h' instead.
#endif
#ifndef incl_HPHP_TV_HELPERS_H_
#define incl_HPHP_TV_HELPERS_H_
#include "hphp/runtime/base/types.h"
namespace HPHP {
@@ -216,11 +216,17 @@ inline void tvDupRef(RefData* fr, TypedValue* to) {
}
// Assumes 'fr' is live and 'to' is dead
// NOTE: this helper does not modify to->_count
inline void tvDup(const TypedValue* fr, TypedValue* to) {
// After this operation, 'fr' is dead and 'to' live.
inline void tvTeleport(const TypedValue* fr, TypedValue* to) {
assert(tvIsPlausible(fr));
to->m_data.num = fr->m_data.num;
to->m_type = fr->m_type;
}
// Assumes 'fr' is live and 'to' is dead
// NOTE: this helper does not modify to->_count
inline void tvDup(const TypedValue* fr, TypedValue* to) {
tvTeleport(fr, to);
tvRefcountedIncRef(to);
}
+5 -2
Ver Arquivo
@@ -383,7 +383,7 @@ void VarEnv::detach(ActRec* fp) {
TypedValue** origLocs =
!m_restoreLocations.empty()
? m_restoreLocations.back()
: reinterpret_cast<TypedValue**>(uintptr_t(this) + sizeof(VarEnv));
: reinterpret_cast<TypedValue**>(uintptr_t(this) + sizeof(VarEnv));
for (Id i = 0; i < numLocals; i++) {
m_nvTable->resettle(func->localVarName(i), origLocs[i]);
@@ -6694,7 +6694,10 @@ static inline void setContVar(const Func* genFunc,
c_Continuation* cont) {
Id destId = genFunc->lookupVarId(name);
if (destId != kInvalidId) {
tvDup(src, frame_local(cont->actRec(), destId));
// Copy the value of the local to the cont object and set the
// local to uninit so that we don't need to change refcounts.
tvTeleport(src, frame_local(cont->actRec(), destId));
tvWriteUninit(src);
} else {
ActRec *contFP = cont->actRec();
if (!contFP->hasVarEnv()) {
+4 -2
Ver Arquivo
@@ -1033,8 +1033,10 @@ void HhbcTranslator::emitCreateCont(Id funNameStrId) {
// We must generate an AssertLoc because we don't have tracelet
// guards on the object type in these outer generator functions.
gen(AssertLoc, Type::Gen, LocalId(i), m_tb->fp());
auto const loc = gen(IncRef, ldLoc(i));
gen(StMem, contAR, cns(-cellsToBytes(params[i] + 1)), loc);
// Copy the value of the local to the cont object and set the
// local to uninit so that we don't need to change refcounts.
gen(StMem, contAR, cns(-cellsToBytes(params[i] + 1)), ldLoc(i));
gen(StLoc, LocalId(i), m_tb->fp(), m_tb->genDefUninit());
}
if (fillThis) {
assert(thisId != kInvalidId);