5 Commits

Autor SHA1 Mensagem Data
Sara Golemon 8b23419a37 HPHP version 2.0.0 2013-03-14 16:00:42 -07:00
ottoni af5623b4fc Properly patch exit traces ending with JmpZero and JmpNZero
The hoistConditionalJumps pass was not handling traces ending with
JmpZero and JmpNZero.  This was resulting in spurious jumps to
'astubs' instead of patching the jcc+jump pair in 'a'.
2013-03-14 15:45:51 -07:00
ptarjan b51003b5aa tell closures about scope clones
In HHBC mode, traits are flattened into their classes.
When that happens, closures need to know about all the
classes that contain them so that when we find a ##$this##
inside the closure, it can tell EVERY containing scope to
please propogate ##$this## down to me.
2013-03-14 15:45:40 -07:00
mwilliams 5f019f5b43 Fix CodeGenerator::cgNInstanceOf
It assumed the result would be in rax, but it isnt always.
Use the correct register.
2013-03-13 10:16:23 -07:00
bertrand 35e347efa5 Fixed ContNext by writing InitNull rather than Uninit.
Apparently, m_received needs to be InitNull, rather than
Uninit.
2013-03-13 10:16:14 -07:00
13 arquivos alterados com 146 adições e 49 exclusões
+31
Ver Arquivo
@@ -25,6 +25,7 @@
#include <compiler/analysis/variable_table.h>
#include <compiler/construct.h>
#include <compiler/expression/class_constant_expression.h>
#include <compiler/expression/closure_expression.h>
#include <compiler/expression/constant_expression.h>
#include <compiler/expression/scalar_expression.h>
#include <compiler/expression/unary_op_expression.h>
@@ -32,6 +33,7 @@
#include <compiler/option.h>
#include <compiler/parser/parser.h>
#include <compiler/statement/interface_statement.h>
#include <compiler/statement/function_statement.h>
#include <compiler/statement/method_statement.h>
#include <compiler/statement/statement_list.h>
#include <runtime/base/builtin_functions.h>
@@ -445,6 +447,7 @@ ClassScope::importTraitMethod(const TraitMethod& traitMethod,
cloneMeth->getModifiers()));
cloneMeth->resetScope(cloneFuncScope, true);
cloneFuncScope->setOuterScope(shared_from_this());
informClosuresAboutScopeClone(cloneMeth, cloneFuncScope, ar);
cloneMeth->addTraitMethodToScope(ar,
dynamic_pointer_cast<ClassScope>(shared_from_this()));
@@ -452,6 +455,34 @@ ClassScope::importTraitMethod(const TraitMethod& traitMethod,
return cloneMeth;
}
void ClassScope::informClosuresAboutScopeClone(
ConstructPtr root,
FunctionScopePtr outerScope,
AnalysisResultPtr ar) {
if (!root) {
return;
}
for (int i = 0; i < root->getKidCount(); i++) {
ConstructPtr cons = root->getNthKid(i);
ClosureExpressionPtr closure =
dynamic_pointer_cast<ClosureExpression>(cons);
if (!closure) {
informClosuresAboutScopeClone(cons, outerScope, ar);
continue;
}
FunctionStatementPtr func = closure->getClosureFunction();
HPHP::FunctionScopePtr funcScope = func->getFunctionScope();
assert(funcScope->isClosure());
funcScope->addClonedTraitOuterScope(outerScope);
// Don't need to recurse
}
}
void ClassScope::addImportTraitMethod(const TraitMethod &traitMethod,
const string &methName) {
m_importMethToTraitMap[methName].push_back(traitMethod);
+3
Ver Arquivo
@@ -437,6 +437,9 @@ private:
void addImportTraitMethod(const TraitMethod &traitMethod,
const std::string &methName);
void informClosuresAboutScopeClone(ConstructPtr root,
FunctionScopePtr outerScope,
AnalysisResultPtr ar);
void setImportTraitMethodModifiers(const std::string &methName,
ClassScopePtr traitCls,
+40
Ver Arquivo
@@ -410,6 +410,46 @@ bool FunctionScope::containsReference() const {
return m_attribute & FileScope::ContainsReference;
}
void FunctionScope::setContainsThis(bool f /* = true */) {
m_containsThis = f;
BlockScopePtr bs(this->getOuterScope());
while (bs && bs->is(BlockScope::FunctionScope)) {
FunctionScopePtr fs = static_pointer_cast<FunctionScope>(bs);
if (!fs->isClosure()) {
break;
}
fs->setContainsThis(f);
bs = bs->getOuterScope();
}
for (auto it = m_clonedTraitOuterScope.begin(); it != m_clonedTraitOuterScope.end(); it++) {
(*it)->setContainsThis(f);
}
}
void FunctionScope::setContainsBareThis(bool f, bool ref /* = false */) {
if (f) {
m_containsBareThis |= ref ? 2 : 1;
} else {
m_containsBareThis = 0;
}
BlockScopePtr bs(this->getOuterScope());
while (bs && bs->is(BlockScope::FunctionScope)) {
FunctionScopePtr fs = static_pointer_cast<FunctionScope>(bs);
if (!fs->isClosure()) {
break;
}
fs->setContainsBareThis(f, ref);
bs = bs->getOuterScope();
}
for (auto it = m_clonedTraitOuterScope.begin(); it != m_clonedTraitOuterScope.end(); it++) {
(*it)->setContainsBareThis(f, ref);
}
}
bool FunctionScope::hasImpl() const {
if (!isUserFunction()) {
return !isAbstract();
+10 -8
Ver Arquivo
@@ -176,6 +176,13 @@ public:
m_volatile = false;
}
/**
* Tell this function about another outer scope that contains it.
*/
void addClonedTraitOuterScope(FunctionScopePtr scope) {
m_clonedTraitOuterScope.push_back(scope);
}
/**
* Get/set original name of the function, without case being lowered.
*/
@@ -237,16 +244,10 @@ public:
* Whether this function contains a usage of $this
*/
bool containsThis() const { return m_containsThis;}
void setContainsThis(bool f=true) { m_containsThis = f;}
void setContainsThis(bool f = true);
bool containsBareThis() const { return m_containsBareThis; }
bool containsRefThis() const { return m_containsBareThis & 2; }
void setContainsBareThis(bool f, bool ref = false) {
if (f) {
m_containsBareThis |= ref ? 2 : 1;
} else {
m_containsBareThis = 0;
}
}
void setContainsBareThis(bool f, bool ref = false);
/**
* How many parameters a caller should provide.
*/
@@ -492,6 +493,7 @@ private:
ExpressionListPtr m_closureValues;
ReadWriteMutex m_inlineMutex;
unsigned m_nextID; // used when cloning generators for traits
std::list<FunctionScopeRawPtr> m_clonedTraitOuterScope;
};
///////////////////////////////////////////////////////////////////////////////
+1 -1
Ver Arquivo
@@ -16,7 +16,7 @@ if (!defined('GLOBAL_SYMBOL_REDECLARED_CLASS')) {define('GLOBAL_SYMBOL_REDECLARE
if (!defined('GLOBAL_SYMBOL_REDECLARED_FUNCTION')) {define('GLOBAL_SYMBOL_REDECLARED_FUNCTION', 5);}
if (!defined('GLOBAL_SYMBOL_STATIC_VARIABLE')) {define('GLOBAL_SYMBOL_STATIC_VARIABLE', 1);}
if (!defined('HPHP_TRIM_CHARLIST')) {define('HPHP_TRIM_CHARLIST', ' \n\r\t\v' . "\0" . '');}
if (!defined('HPHP_VERSION')) {define('HPHP_VERSION', '1.0.0');}
if (!defined('HPHP_VERSION')) {define('HPHP_VERSION', '2.0.0');}
if (!defined('INI_SCANNER_NORMAL')) {define('INI_SCANNER_NORMAL', 0);}
if (!defined('INI_SCANNER_RAW')) {define('INI_SCANNER_RAW', 1);}
if (!defined('PHP_VERSION')) {define('PHP_VERSION', '5.3.3.hiphop');}
+7 -25
Ver Arquivo
@@ -222,26 +222,6 @@ pathloop:
}
}
ConditionCode cmpOpToCC(Opcode opc) {
switch (opc) {
case OpGt: return CC_G;
case OpGte: return CC_GE;
case OpLt: return CC_L;
case OpLte: return CC_LE;
case OpEq: return CC_E;
case OpNeq: return CC_NE;
case OpSame: return CC_E;
case OpNSame: return CC_NE;
case InstanceOf: return CC_NZ;
case NInstanceOf: return CC_Z;
case InstanceOfBitmask: return CC_NZ;
case NInstanceOfBitmask: return CC_Z;
case IsType: return CC_NZ;
case IsNType: return CC_Z;
default: always_assert(0);
}
}
const char* getContextName(Class* ctx) {
return ctx ? ctx->name()->data() : ":anonymous:";
}
@@ -534,7 +514,7 @@ void CodeGenerator::cgJcc(IRInstruction* inst) {
SSATmp* src1 = inst->getSrc(0);
SSATmp* src2 = inst->getSrc(1);
Opcode opc = inst->getOpcode();
ConditionCode cc = cmpOpToCC(queryJmpToQueryOp(opc));
ConditionCode cc = queryJmpToCC(opc);
Type src1Type = src1->getType();
Type src2Type = src2->getType();
@@ -1467,10 +1447,12 @@ void CodeGenerator::cgInstanceOf(IRInstruction* inst) {
void CodeGenerator::cgNInstanceOf(IRInstruction* inst) {
// TODO(#2058865): having NInstanceOf is no better than InstanceOf
// followed by boolean Not opcode.
emitInstanceCheck(inst, inst->getDst()->getReg());
PhysReg dstReg = inst->getDst()->getReg();
emitInstanceCheck(inst, dstReg);
Reg8 dr((int(dstReg)));
auto& a = m_as;
a. testb (al, al);
a. setz (al);
a. testb (dr, dr);
a. setz (dr);
}
void CodeGenerator::cgJmpInstanceOf(IRInstruction* inst) {
@@ -2251,7 +2233,7 @@ void CodeGenerator::cgExitTrace(IRInstruction* inst) {
// Patch the original jcc;jmp, don't emit another
IRInstruction* jcc = toSmash->getInstruction();
Opcode opc = jcc->getOpcode();
ConditionCode cc = cmpOpToCC(queryJmpToQueryOp(opc));
ConditionCode cc = queryJmpToCC(opc);
uint64_t taken = pc->getValInt();
uint64_t notTaken = notTakenPC->getValInt();
@@ -772,14 +772,10 @@ void HhbcTranslator::emitContDone() {
}
void HhbcTranslator::emitContNext() {
emitInterpOneOrPunt(Type::None);
return;
// Task #2140912: Fix and re-enable this
assert(getCurClass());
SSATmp* cont = m_tb->genLdThis(nullptr);
m_tb->genContPreNext(cont, getExitSlowTrace());
m_tb->genSetPropCell(cont, CONTOFF(m_received), m_tb->genDefUninit());
m_tb->genSetPropCell(cont, CONTOFF(m_received), m_tb->genDefInitNull());
}
void HhbcTranslator::emitContSendImpl(bool raise) {
+47 -1
Ver Arquivo
@@ -629,14 +629,60 @@ inline Opcode queryToJmpOp(Opcode opc) {
}
inline bool isQueryJmpOp(Opcode opc) {
return opc >= JmpGt && opc <= JmpIsNType;
switch (opc) {
case JmpGt:
case JmpGte:
case JmpLt:
case JmpLte:
case JmpEq:
case JmpNeq:
case JmpSame:
case JmpNSame:
case JmpInstanceOf:
case JmpNInstanceOf:
case JmpInstanceOfBitmask:
case JmpNInstanceOfBitmask:
case JmpIsType:
case JmpIsNType:
case JmpZero:
case JmpNZero:
return true;
default:
return false;
}
}
inline Opcode queryJmpToQueryOp(Opcode opc) {
assert(isQueryJmpOp(opc));
assert(opc != JmpZero && opc != JmpNZero);
return Opcode(OpGt + (opc - JmpGt));
}
inline ConditionCode queryJmpToCC(Opcode opc) {
assert(isQueryJmpOp(opc));
switch (opc) {
case JmpGt: return CC_G;
case JmpGte: return CC_GE;
case JmpLt: return CC_L;
case JmpLte: return CC_LE;
case JmpEq: return CC_E;
case JmpNeq: return CC_NE;
case JmpSame: return CC_E;
case JmpNSame: return CC_NE;
case JmpInstanceOf: return CC_NZ;
case JmpNInstanceOf: return CC_Z;
case JmpInstanceOfBitmask: return CC_NZ;
case JmpNInstanceOfBitmask: return CC_Z;
case JmpIsType: return CC_NZ;
case JmpIsNType: return CC_Z;
case JmpZero: return CC_Z;
case JmpNZero: return CC_NZ;
default:
not_reached();
}
}
/*
* Right now branch fusion is too indiscriminate to handle fusing
* with potentially expensive-to-repeat operations. TODO(#2053369)
+1 -4
Ver Arquivo
@@ -23,10 +23,7 @@ namespace HPHP { namespace VM { namespace JIT {
// These are the conditional branches supported for direct branch
// to their target trace at TraceExit, TraceExitType::NormalCc
static bool jccCanBeDirectExit(Opcode opc) {
// JmpGt .. JmpNSame are contiguous and all use cgJcc
return (JmpGt <= opc && opc <= JmpNSame) ||
opc == JmpInstanceOf || opc == JmpNInstanceOf ||
opc == JmpInstanceOfBitmask || opc == JmpNInstanceOfBitmask;
return isQueryJmpOp(opc) && (opc != JmpIsType) && (opc != JmpIsNType);
// TODO(#2053369): JmpIsType, etc
}
+2 -2
Ver Arquivo
@@ -457,7 +457,7 @@ const int64_t k_GRAPHEME_EXTR_MAXBYTES = 1;
const int64_t k_GRAPHEME_EXTR_MAXCHARS = 2;
const int64_t k_HASH_HMAC = 1;
extern const StaticString k_HPHP_TRIM_CHARLIST("\n\r\t\v\000 ",6);
extern const StaticString k_HPHP_VERSION("1.0.0",5);
extern const StaticString k_HPHP_VERSION("2.0.0",5);
const int64_t k_HTML_ENTITIES = 1;
const int64_t k_HTML_SPECIALCHARS = 0;
extern const StaticString k_ICONV_IMPL("glibc",5);
@@ -17963,7 +17963,7 @@ const char *g_class_map[] = {
"GRAPHEME_EXTR_MAXCHARS", (const char*)4, "i:2;",
"HASH_HMAC", (const char*)4, "i:1;",
"HPHP_TRIM_CHARLIST", (const char*)13, "s:6:\"\n\r\t\v\000 \";",
"HPHP_VERSION", (const char*)12, "s:5:\"1.0.0\";",
"HPHP_VERSION", (const char*)12, "s:5:\"2.0.0\";",
"HTML_ENTITIES", (const char*)4, "i:1;",
"HTML_SPECIALCHARS", (const char*)4, "i:0;",
"ICONV_IMPL", (const char*)12, "s:5:\"glibc\";",
+1 -1
Ver Arquivo
@@ -445,7 +445,7 @@ define('GRAPHEME_EXTR_MAXBYTES', 1);
define('GRAPHEME_EXTR_MAXCHARS', 2);
define('HASH_HMAC', 1);
define('HPHP_TRIM_CHARLIST', "\n\r\t\v\000 ");
define('HPHP_VERSION', "1.0.0");
define('HPHP_VERSION', "2.0.0");
define('HTML_ENTITIES', 1);
define('HTML_SPECIALCHARS', 0);
define('ICONV_IMPL', "glibc");
+1 -1
Ver Arquivo
@@ -2670,7 +2670,7 @@ DefineConstant(
DefineConstant(
array(
'name' => "HPHP_VERSION",
'value' => "1.0.0",
'value' => "2.0.0",
));
DefineConstant(
+1 -1
Ver Arquivo
@@ -1 +1 @@
HPHP_VERSION(1.000)
HPHP_VERSION(2.0.0)