Do not cache units containing eval code created by debugger

A number of debugger commands end up doing an eval inside the VM. These eval's are ad-hoc and are performed in human time scales. There is no need to cache them. Consequently, call compile_string directly, rather than call it via compileEvalString (which does caching). Also make sure that the result of compile_string is always interpreted so that no JIT caching happens.

In principle, caching ought not to matter, but another bug is causing the JIT to fail an assertion if a cached eval string is recompiled in a context where variables that were bound are no longer bound.

Differential Revision: D904873
Esse commit está contido em:
Herman Venter
2013-08-01 10:45:54 -07:00
commit de Sara Golemon
commit 52503f5ea8
5 arquivos alterados com 45 adições e 3 exclusões
+10 -3
Ver Arquivo
@@ -1508,10 +1508,15 @@ void VMExecutionContext::syncGdbState() {
}
}
static bool jitIsEnabled(const Unit* unit) {
if (!ThreadInfo::s_threadInfo->m_reqInjectionData.getJit()) return false;
return unit == nullptr || !unit->isInterpretOnly();
}
void VMExecutionContext::enterVMPrologue(ActRec* enterFnAr) {
assert(enterFnAr);
Stats::inc(Stats::VMEnter);
if (ThreadInfo::s_threadInfo->m_reqInjectionData.getJit()) {
if (jitIsEnabled(enterFnAr->m_func->unit())) {
int np = enterFnAr->m_func->numParams();
int na = enterFnAr->numArgs();
if (na > np) na = np + 1;
@@ -1532,7 +1537,7 @@ void VMExecutionContext::enterVMWork(ActRec* enterFnAr) {
start = enterFnAr->m_func->getFuncBody();
}
Stats::inc(Stats::VMEnter);
if (ThreadInfo::s_threadInfo->m_reqInjectionData.getJit()) {
if (jitIsEnabled(m_fp->unit())) {
(void) m_fp->unit()->offsetOf(m_pc); /* assert */
if (enterFnAr) {
assert(start);
@@ -2570,12 +2575,14 @@ void VMExecutionContext::evalPHPDebugger(TypedValue* retval, StringData *code,
int frame) {
assert(retval);
// The code has "<?php" prepended already
Unit* unit = compileEvalString(code);
Unit* unit = compile_string(code->data(), code->size());
if (unit == nullptr) {
raise_error("Syntax error");
tvWriteNull(retval);
return;
}
// Do not JIT this unit, we are using it exactly once.
unit->setInterpretOnly();
VarEnv *varEnv = nullptr;
ActRec *fp = getFP();