Skip to content

Commit

Permalink
Streamline Unit::merge
Browse files Browse the repository at this point in the history
Summary:
We're still spending a lot of time in Unit::merge.
This optimizes defClass and defFunc for the case
where the class/func is known to be unique. It also
fixes various issues in the emitter so that builtin
classes and functions, closures and continuations
are all marked as unique.
  • Loading branch information
mwilliams authored and Joel Pobar committed Sep 27, 2012
1 parent 77cd177 commit 20fc5e2
Show file tree
Hide file tree
Showing 12 changed files with 362 additions and 156 deletions.
64 changes: 47 additions & 17 deletions src/compiler/analysis/emitter.cpp
Expand Up @@ -1023,9 +1023,17 @@ void MetaInfoBuilder::setForUnit(UnitEmitter& target) const {
free(meta);
}

static StringData* continuationClassName(const StringData* fname) {
StringData* EmitterVisitor::continuationClassName(
const StringData* fname) {
std::ostringstream str;
str << "continuation$" << fname->data();
str << "continuation$"
<< '$'
<< std::hex
<< m_curFunc->ue().md5().q[1] << m_curFunc->ue().md5().q[0]
<< std::dec
<< '$'
<< fname->data();

return StringData::GetStaticString(str.str());
}

Expand Down Expand Up @@ -3400,7 +3408,7 @@ bool EmitterVisitor::visitImpl(ConstructPtr node) {
const Location* sLoc = ce->getLocation().get();
PreClassEmitter* pce = m_ue.newPreClassEmitter(className,
PreClass::NotHoistable);
pce->init(sLoc->line0, sLoc->line1, m_ue.bcPos(), AttrNone,
pce->init(sLoc->line0, sLoc->line1, m_ue.bcPos(), AttrUnique,
parentName, NULL);
e.DefCls(pce->id());

Expand Down Expand Up @@ -4741,6 +4749,9 @@ void EmitterVisitor::emitPostponedMeths() {
attrs = (Attr)(attrs | AttrNoOverride);
}
}
} else if (!SystemLib::s_inited) {
// we're building systemlib. everything is unique
attrs = (Attr)(attrs | AttrUnique);
}

// For closures, the MethodStatement didn't have real attributes; enforce
Expand Down Expand Up @@ -4869,7 +4880,7 @@ void EmitterVisitor::newContinuationClass(const StringData* name) {
StringData::GetStaticString("GenericContinuation");
PreClassEmitter* pce = m_ue.newPreClassEmitter(className,
PreClass::AlwaysHoistable);
pce->init(0, 0, m_ue.bcPos(), AttrNone, parentName, NULL);
pce->init(0, 0, m_ue.bcPos(), AttrUnique, parentName, NULL);
}

void EmitterVisitor::emitPostponedCtors() {
Expand Down Expand Up @@ -5335,19 +5346,26 @@ PreClass::Hoistable EmitterVisitor::emitClass(Emitter& e, ClassScopePtr cNode,
if (cNode->getUsedTraitNames().size()) {
attr = (Attr)(attr | AttrNoExpandTrait);
}
} else if (!SystemLib::s_inited) {
// we're building systemlib. everything is unique
attr = (Attr)(attr | AttrUnique);
}

const Location* sLoc = is->getLocation().get();
const std::vector<std::string>& bases(cNode->getBases());
int firstInterface = cNode->getOriginalParent().empty() ? 0 : 1;
int nInterfaces = bases.size();
PreClass::Hoistable hoistable = PreClass::NotHoistable;
if (toplevel) {
if (nInterfaces > firstInterface || cNode->getUsedTraitNames().size()) {
hoistable = PreClass::Mergeable;
} else if (firstInterface &&
!m_hoistables.count(cNode->getOriginalParent())) {
hoistable = PreClass::MaybeHoistable;
} else {
if (SystemLib::s_inited) {
if (nInterfaces > firstInterface || cNode->getUsedTraitNames().size()) {
hoistable = PreClass::Mergeable;
} else if (firstInterface &&
!m_hoistables.count(cNode->getOriginalParent())) {
hoistable = PreClass::MaybeHoistable;
}
}
if (hoistable == PreClass::NotHoistable) {
hoistable = PreClass::AlwaysHoistable;
m_hoistables.insert(cNode->getOriginalName());
}
Expand Down Expand Up @@ -5867,16 +5885,20 @@ StringData* EmitterVisitor::newClosureName() {
if (m_curFunc->pce() != NULL) {
str << m_curFunc->pce()->name()->data();
}
str << "$";
str << '$';
if (m_curFunc->isPseudoMain()) {
// Pseudo-main. Uniquify via md5.
str << "__pseudoMain" << std::hex
<< m_curFunc->ue().md5().q[1] << m_curFunc->ue().md5().q[0]
<< std::dec;
str << "__pseudoMain";
} else {
str << m_curFunc->name()->data();
}
str << "$" << m_closureCounter++;
/*
* Uniquify the name
*/
str << '$'
<< std::hex
<< m_curFunc->ue().md5().q[1] << m_curFunc->ue().md5().q[0]
<< std::dec
<< '$' << m_closureCounter++;

return StringData::GetStaticString(str.str());
}
Expand Down Expand Up @@ -6067,6 +6089,7 @@ static Unit* emitHHBCNativeFuncUnit(const HhbcExtFuncInfo* builtinFuncs,
ue->emitOp(OpNativeImpl);
Offset past = ue->bcPos();
fe->setMaxStackCells(kNumActRecCells + 1);
fe->setAttrs(Attr(fe->attrs()|AttrUnique));
fe->finish(past, false);
ue->recordFunction(fe);
}
Expand Down Expand Up @@ -6171,6 +6194,13 @@ static Unit* emitHHBCNativeClassUnit(const HhbcExtClassInfo* builtinClasses,
mfe->finish(past, false);
ue->recordFunction(mfe);

TypedValue mainReturn;
mainReturn.m_data.num = 1;
mainReturn.m_type = KindOfBoolean;
// _count is the "Unit::isMergeOnly()" flag
mainReturn._count = 1;
ue->setMainReturn(&mainReturn);

MetaInfoBuilder metaInfo;

ContMethMap contMethods;
Expand Down Expand Up @@ -6238,7 +6268,7 @@ static Unit* emitHHBCNativeClassUnit(const HhbcExtClassInfo* builtinClasses,
StringData::GetStaticString(e.ci->getParentClass().get());
PreClassEmitter* pce = ue->newPreClassEmitter(e.name,
PreClass::AlwaysHoistable);
pce->init(0, 0, ue->bcPos(), AttrNone, parentName, NULL);
pce->init(0, 0, ue->bcPos(), AttrUnique, parentName, NULL);
pce->setBuiltinClassInfo(e.ci, e.info->m_InstanceCtor, e.info->m_sizeof);
{
ClassInfo::InterfaceVec intfVec = e.ci->getInterfacesVec();
Expand Down
1 change: 1 addition & 0 deletions src/compiler/analysis/emitter.h
Expand Up @@ -570,6 +570,7 @@ class EmitterVisitor {
void saveMaxStackCells(FuncEmitter* fe);
void finishFunc(Emitter& e, FuncEmitter* fe);
StringData* newClosureName();
StringData* continuationClassName(const StringData* fname);
void newContinuationClass(const StringData* name);

void initScalar(TypedValue& tvVal, ExpressionPtr val);
Expand Down
21 changes: 0 additions & 21 deletions src/runtime/base/program_functions.cpp
Expand Up @@ -55,8 +55,6 @@
#include <runtime/base/util/simple_counter.h>
#include <runtime/base/util/extended_logger.h>

#include <runtime/vm/translator/translator-x64.h>

#include <boost/program_options/options_description.hpp>
#include <boost/program_options/positional_options.hpp>
#include <boost/program_options/variables_map.hpp>
Expand Down Expand Up @@ -1131,26 +1129,7 @@ void hphp_process_init() {
init_literal_varstrings();

if (hhvm) {
if (!RuntimeOption::RepoAuthoritative &&
RuntimeOption::EvalJitEnableRenameFunction &&
RuntimeOption::EvalJit) {
VM::Func::enableIntercept();
VM::Transl::TranslatorX64* tx64 = VM::Transl::TranslatorX64::Get();
tx64->enableIntercepts();
}
bool db = RuntimeOption::EvalDumpBytecode;
bool p = RuntimeOption::RepoAuthoritative;
bool rp = RuntimeOption::AlwaysUseRelativePath;
bool sf = RuntimeOption::SafeFileAccess;
RuntimeOption::EvalDumpBytecode = false;
RuntimeOption::RepoAuthoritative = false;
RuntimeOption::AlwaysUseRelativePath = false;
RuntimeOption::SafeFileAccess = false;
HPHP::VM::ProcessInit();
RuntimeOption::EvalDumpBytecode = db;
RuntimeOption::RepoAuthoritative = p;
RuntimeOption::AlwaysUseRelativePath = rp;
RuntimeOption::SafeFileAccess = sf;
}

PageletServer::Restart();
Expand Down
13 changes: 9 additions & 4 deletions src/runtime/vm/bytecode.cpp
Expand Up @@ -2022,6 +2022,15 @@ void VMExecutionContext::invokeFunc(TypedValue* retval,

checkStack(m_stack, f);

if (toMerge != NULL) {
ASSERT(toMerge->getMain() == f);
toMerge->merge();
if (toMerge->isMergeOnly()) {
*retval = *toMerge->getMainReturn();
return;
}
}

ActRec* ar = m_stack.allocA();
ar->m_soff = 0;
ar->m_savedRbp = 0;
Expand Down Expand Up @@ -2109,10 +2118,6 @@ void VMExecutionContext::invokeFunc(TypedValue* retval,
}
}

if (toMerge != NULL) {
toMerge->merge();
}

if (m_fp) {
reenterVM(retval, ar, extraArgs, savedSP);
} else {
Expand Down
8 changes: 8 additions & 0 deletions src/runtime/vm/translator/targetcache.cpp
Expand Up @@ -487,6 +487,14 @@ GlobalCache::lookupCreate(Handle handle, StringData* name) {
return retval;
}

TypedValue*
GlobalCache::lookupCreateAddr(void* cacheAddr, StringData* name) {
GlobalCache* thiz = (GlobalCache*)cacheAddr;
TypedValue* retval = thiz->lookupImpl<false>(name, true /* allowCreate */);
ASSERT(retval->m_type != KindOfRef);
return retval;
}

TypedValue*
BoxedGlobalCache::lookup(Handle handle, StringData* name) {
BoxedGlobalCache* thiz = (BoxedGlobalCache*)
Expand Down
1 change: 1 addition & 0 deletions src/runtime/vm/translator/targetcache.h
Expand Up @@ -401,6 +401,7 @@ class GlobalCache {

static TypedValue* lookup(CacheHandle handle, StringData* nm);
static TypedValue* lookupCreate(CacheHandle handle, StringData* nm);
static TypedValue* lookupCreateAddr(void* cacheAddr, StringData* nm);
};

class BoxedGlobalCache : public GlobalCache {
Expand Down
6 changes: 3 additions & 3 deletions src/runtime/vm/translator/translator-x64.cpp
Expand Up @@ -10288,9 +10288,9 @@ TranslatorX64::emitGetGlobal(const NormalizedInstruction& i, int nameIdx,
}
SKTRACE(1, i.source, "ch %d\n", ch);
EMIT_CALL(a, allowCreate ? GlobalCache::lookupCreate
: GlobalCache::lookup,
IMM(ch),
IMM((uint64_t)maybeName));
: GlobalCache::lookup,
IMM(ch),
IMM((uint64_t)maybeName));
recordCall(i);
}

Expand Down

0 comments on commit 20fc5e2

Please sign in to comment.