Add syntax checker for side-effect-free expressions to AstOptimizer in rewriter.cc. Add bit fields for syntax checker results to Expression in ast.h.
Review URL: http://codereview.chromium.org/660372 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3998 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
b021997f81
commit
7657955f3f
61
src/ast.h
61
src/ast.h
@ -183,7 +183,11 @@ class Expression: public AstNode {
|
||||
|
||||
static const int kNoLabel = -1;
|
||||
|
||||
Expression() : num_(kNoLabel), def_(NULL), defined_vars_(NULL) {}
|
||||
Expression()
|
||||
: bitfields_(0),
|
||||
num_(kNoLabel),
|
||||
def_(NULL),
|
||||
defined_vars_(NULL) {}
|
||||
|
||||
virtual Expression* AsExpression() { return this; }
|
||||
|
||||
@ -225,11 +229,66 @@ class Expression: public AstNode {
|
||||
defined_vars_ = defined_vars;
|
||||
}
|
||||
|
||||
// AST analysis results
|
||||
|
||||
// True if the expression rooted at this node can be compiled by the
|
||||
// side-effect free compiler.
|
||||
bool side_effect_free() { return SideEffectFreeField::decode(bitfields_); }
|
||||
void set_side_effect_free(bool is_side_effect_free) {
|
||||
bitfields_ = (bitfields_ & ~SideEffectFreeField::mask()) |
|
||||
SideEffectFreeField::encode(is_side_effect_free);
|
||||
}
|
||||
|
||||
// The number of unary and binary operations contained in the expression
|
||||
// rooted at this node. Valid only if side_effect_free() is true.
|
||||
int expression_size() { return ExpressionSizeField::decode(bitfields_); }
|
||||
void set_expression_size(int expression_size) {
|
||||
bitfields_ = (bitfields_ & ~ExpressionSizeField::mask()) |
|
||||
ExpressionSizeField::encode(Min(expression_size, ExpressionSizeMax));
|
||||
}
|
||||
|
||||
// The number of expression stack slots needed to compute the expression
|
||||
// rooted at this node. Does not count the slot needed by the value
|
||||
// computed by this expression. Valid only if side_effect_free() is true.
|
||||
int stack_height() { return StackHeightField::decode(bitfields_); }
|
||||
void set_stack_height(int stack_height) {
|
||||
bitfields_ &= ~StackHeightField::mask();
|
||||
bitfields_ |=
|
||||
StackHeightField::encode(Min(stack_height, StackHeightMax));
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t bitfields_;
|
||||
StaticType type_;
|
||||
|
||||
int num_;
|
||||
DefinitionInfo* def_;
|
||||
ZoneList<DefinitionInfo*>* defined_vars_;
|
||||
|
||||
static const int SideEffectFreeFieldStart = 0;
|
||||
static const int SideEffectFreeFieldLength = 1;
|
||||
class SideEffectFreeField: public BitField<bool,
|
||||
SideEffectFreeFieldStart,
|
||||
SideEffectFreeFieldLength> {
|
||||
};
|
||||
|
||||
static const int ExpressionSizeFieldStart =
|
||||
SideEffectFreeFieldStart + SideEffectFreeFieldLength;
|
||||
static const int ExpressionSizeFieldLength = 5;
|
||||
static const int ExpressionSizeMax = (1 << ExpressionSizeFieldLength) - 1;
|
||||
class ExpressionSizeField: public BitField<int,
|
||||
ExpressionSizeFieldStart,
|
||||
ExpressionSizeFieldLength> {
|
||||
};
|
||||
|
||||
static const int StackHeightFieldStart =
|
||||
ExpressionSizeFieldStart + ExpressionSizeFieldLength;
|
||||
static const int StackHeightFieldLength = 5;
|
||||
static const int StackHeightMax = (1 << StackHeightFieldLength) - 1;
|
||||
class StackHeightField: public BitField<int,
|
||||
StackHeightFieldStart,
|
||||
StackHeightFieldLength> {
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
@ -244,6 +244,14 @@ void AstOptimizer::VisitVariableProxy(VariableProxy* node) {
|
||||
!Heap::result_symbol()->Equals(*var->name())) {
|
||||
func_name_inferrer_.PushName(var->name());
|
||||
}
|
||||
|
||||
if (var->slot() != NULL) {
|
||||
Slot* slot = var->slot();
|
||||
node->set_side_effect_free(
|
||||
(slot->type() == Slot::LOCAL && !slot->is_arguments()) ||
|
||||
slot->type() == Slot::PARAMETER));
|
||||
// stack_height and expression_size remain 0.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,11 +260,16 @@ void AstOptimizer::VisitLiteral(Literal* node) {
|
||||
Handle<Object> literal = node->handle();
|
||||
if (literal->IsSmi()) {
|
||||
node->type()->SetAsLikelySmi();
|
||||
node->set_side_effect_free(true);
|
||||
// stack_height and expression_size remain 0.
|
||||
} else if (literal->IsString()) {
|
||||
Handle<String> lit_str(Handle<String>::cast(literal));
|
||||
if (!Heap::prototype_symbol()->Equals(*lit_str)) {
|
||||
func_name_inferrer_.PushName(lit_str);
|
||||
}
|
||||
} else if (literal->IsHeapNumber()) {
|
||||
node->set_side_effect_free(true);
|
||||
// stack_height and expression_size remain 0.
|
||||
}
|
||||
}
|
||||
|
||||
@ -414,6 +427,23 @@ void AstOptimizer::VisitCallRuntime(CallRuntime* node) {
|
||||
|
||||
void AstOptimizer::VisitUnaryOperation(UnaryOperation* node) {
|
||||
Visit(node->expression());
|
||||
switch (node->op()) {
|
||||
case Token::ADD:
|
||||
case Token::SUB:
|
||||
node->set_side_effect_free(node->expression()->side_effect_free());
|
||||
node->set_expression_size(node->expression()->expression_size() + 1);
|
||||
node->set_stack_height(node->expression()->stack_height());
|
||||
break;
|
||||
case Token::DELETE:
|
||||
case Token::TYPEOF:
|
||||
case Token::VOID:
|
||||
case Token::BIT_NOT:
|
||||
case Token::NOT:
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -483,6 +513,33 @@ void AstOptimizer::VisitBinaryOperation(BinaryOperation* node) {
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (node->op()) {
|
||||
case Token::COMMA:
|
||||
case Token::OR:
|
||||
case Token::AND:
|
||||
case Token::BIT_OR:
|
||||
case Token::BIT_XOR:
|
||||
case Token::BIT_AND:
|
||||
case Token::SHL:
|
||||
case Token::SAR:
|
||||
case Token::SHR:
|
||||
case Token::MOD:
|
||||
break;
|
||||
case Token::ADD:
|
||||
case Token::SUB:
|
||||
case Token::MUL:
|
||||
case Token::DIV:
|
||||
node->set_side_effect_free(node->left()->side_effect_free() &&
|
||||
node->right()->side_effect_free());
|
||||
node->set_expression_size(node->left()->expression_size() +
|
||||
node->right()->expression_size() + 1);
|
||||
node->set_stack_height(Max(node->left()->stack_height(),
|
||||
node->right()->stack_height() + 1));
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user