Chromium Code Reviews| Index: src/ast.cc |
| diff --git a/src/ast.cc b/src/ast.cc |
| index 811193b49bde08c34da5f54648a90b0542c4ab89..43b9273e10069ccb1a7d94ec6796817e5fad894c 100644 |
| --- a/src/ast.cc |
| +++ b/src/ast.cc |
| @@ -115,7 +115,8 @@ Assignment::Assignment(Isolate* isolate, |
| Token::Value op, |
| Expression* target, |
| Expression* value, |
| - int pos) |
| + int pos, |
| + AstNodeFactory* factory) |
| : Expression(isolate), |
| op_(op), |
| target_(target), |
| @@ -130,11 +131,7 @@ Assignment::Assignment(Isolate* isolate, |
| ASSERT(Token::IsAssignmentOp(op)); |
| if (is_compound()) { |
| binary_operation_ = |
| - new(isolate->zone()) BinaryOperation(isolate, |
| - binary_op(), |
| - target, |
| - value, |
| - pos + 1); |
| + factory->NewBinaryOperation(binary_op(), target, value, pos + 1); |
| compound_load_id_ = GetNextId(isolate); |
| } |
| } |
| @@ -179,6 +176,16 @@ LanguageMode FunctionLiteral::language_mode() const { |
| } |
| +bool FunctionLiteral::ShouldSelfOptimize() { |
| + return !ast_properties()->flags()->Contains(kDontSelfOptimize); |
| +} |
| + |
| + |
| +int FunctionLiteral::AstNodeCount() { |
| + return ast_properties()->node_count(); |
| +} |
| + |
| + |
| ObjectLiteral::Property::Property(Literal* key, Expression* value) { |
| emit_store_ = true; |
| key_ = key; |
| @@ -196,10 +203,11 @@ ObjectLiteral::Property::Property(Literal* key, Expression* value) { |
| } |
| -ObjectLiteral::Property::Property(bool is_getter, FunctionLiteral* value) { |
| - Isolate* isolate = Isolate::Current(); |
| +ObjectLiteral::Property::Property(bool is_getter, |
| + FunctionLiteral* value, |
| + AstNodeFactory* factory) { |
| emit_store_ = true; |
| - key_ = new(isolate->zone()) Literal(isolate, value->name()); |
| + key_ = factory->NewLiteral(value->name()); |
| value_ = value; |
| kind_ = is_getter ? GETTER : SETTER; |
| } |
| @@ -431,223 +439,6 @@ bool Declaration::IsInlineable() const { |
| } |
| -bool TargetCollector::IsInlineable() const { |
| - UNREACHABLE(); |
| - return false; |
| -} |
| - |
| - |
| -bool ForInStatement::IsInlineable() const { |
| - return false; |
| -} |
| - |
| - |
| -bool WithStatement::IsInlineable() const { |
| - return false; |
| -} |
| - |
| - |
| -bool SwitchStatement::IsInlineable() const { |
| - return false; |
| -} |
| - |
| - |
| -bool TryStatement::IsInlineable() const { |
| - return false; |
| -} |
| - |
| - |
| -bool TryCatchStatement::IsInlineable() const { |
| - return false; |
| -} |
| - |
| - |
| -bool TryFinallyStatement::IsInlineable() const { |
| - return false; |
| -} |
| - |
| - |
| -bool DebuggerStatement::IsInlineable() const { |
| - return false; |
| -} |
| - |
| - |
| -bool Throw::IsInlineable() const { |
| - return exception()->IsInlineable(); |
| -} |
| - |
| - |
| -bool MaterializedLiteral::IsInlineable() const { |
| - // TODO(1322): Allow materialized literals. |
| - return false; |
| -} |
| - |
| - |
| -bool FunctionLiteral::IsInlineable() const { |
| - // TODO(1322): Allow materialized literals. |
| - return false; |
| -} |
| - |
| - |
| -bool ThisFunction::IsInlineable() const { |
| - return true; |
| -} |
| - |
| - |
| -bool SharedFunctionInfoLiteral::IsInlineable() const { |
| - return false; |
| -} |
| - |
| - |
| -bool ForStatement::IsInlineable() const { |
| - return (init() == NULL || init()->IsInlineable()) |
| - && (cond() == NULL || cond()->IsInlineable()) |
| - && (next() == NULL || next()->IsInlineable()) |
| - && body()->IsInlineable(); |
| -} |
| - |
| - |
| -bool WhileStatement::IsInlineable() const { |
| - return cond()->IsInlineable() |
| - && body()->IsInlineable(); |
| -} |
| - |
| - |
| -bool DoWhileStatement::IsInlineable() const { |
| - return cond()->IsInlineable() |
| - && body()->IsInlineable(); |
| -} |
| - |
| - |
| -bool ContinueStatement::IsInlineable() const { |
| - return true; |
| -} |
| - |
| - |
| -bool BreakStatement::IsInlineable() const { |
| - return true; |
| -} |
| - |
| - |
| -bool EmptyStatement::IsInlineable() const { |
| - return true; |
| -} |
| - |
| - |
| -bool Literal::IsInlineable() const { |
| - return true; |
| -} |
| - |
| - |
| -bool Block::IsInlineable() const { |
| - const int count = statements_.length(); |
| - for (int i = 0; i < count; ++i) { |
| - if (!statements_[i]->IsInlineable()) return false; |
| - } |
| - return true; |
| -} |
| - |
| - |
| -bool ExpressionStatement::IsInlineable() const { |
| - return expression()->IsInlineable(); |
| -} |
| - |
| - |
| -bool IfStatement::IsInlineable() const { |
| - return condition()->IsInlineable() |
| - && then_statement()->IsInlineable() |
| - && else_statement()->IsInlineable(); |
| -} |
| - |
| - |
| -bool ReturnStatement::IsInlineable() const { |
| - return expression()->IsInlineable(); |
| -} |
| - |
| - |
| -bool Conditional::IsInlineable() const { |
| - return condition()->IsInlineable() && then_expression()->IsInlineable() && |
| - else_expression()->IsInlineable(); |
| -} |
| - |
| - |
| -bool VariableProxy::IsInlineable() const { |
| - return var()->IsUnallocated() |
| - || var()->IsStackAllocated() |
| - || var()->IsContextSlot(); |
| -} |
| - |
| - |
| -bool Assignment::IsInlineable() const { |
| - return target()->IsInlineable() && value()->IsInlineable(); |
| -} |
| - |
| - |
| -bool Property::IsInlineable() const { |
| - return obj()->IsInlineable() && key()->IsInlineable(); |
| -} |
| - |
| - |
| -bool Call::IsInlineable() const { |
| - if (!expression()->IsInlineable()) return false; |
| - const int count = arguments()->length(); |
| - for (int i = 0; i < count; ++i) { |
| - if (!arguments()->at(i)->IsInlineable()) return false; |
| - } |
| - return true; |
| -} |
| - |
| - |
| -bool CallNew::IsInlineable() const { |
| - if (!expression()->IsInlineable()) return false; |
| - const int count = arguments()->length(); |
| - for (int i = 0; i < count; ++i) { |
| - if (!arguments()->at(i)->IsInlineable()) return false; |
| - } |
| - return true; |
| -} |
| - |
| - |
| -bool CallRuntime::IsInlineable() const { |
| - // Don't try to inline JS runtime calls because we don't (currently) even |
| - // optimize them. |
| - if (is_jsruntime()) return false; |
| - // Don't inline the %_ArgumentsLength or %_Arguments because their |
| - // implementation will not work. There is no stack frame to get them |
| - // from. |
| - if (function()->intrinsic_type == Runtime::INLINE && |
| - (name()->IsEqualTo(CStrVector("_ArgumentsLength")) || |
| - name()->IsEqualTo(CStrVector("_Arguments")))) { |
| - return false; |
| - } |
| - const int count = arguments()->length(); |
| - for (int i = 0; i < count; ++i) { |
| - if (!arguments()->at(i)->IsInlineable()) return false; |
| - } |
| - return true; |
| -} |
| - |
| - |
| -bool UnaryOperation::IsInlineable() const { |
| - return expression()->IsInlineable(); |
| -} |
| - |
| - |
| -bool BinaryOperation::IsInlineable() const { |
| - return left()->IsInlineable() && right()->IsInlineable(); |
| -} |
| - |
| - |
| -bool CompareOperation::IsInlineable() const { |
| - return left()->IsInlineable() && right()->IsInlineable(); |
| -} |
| - |
| - |
| -bool CountOperation::IsInlineable() const { |
| - return expression()->IsInlineable(); |
| -} |
| - |
| - |
| // ---------------------------------------------------------------------------- |
| // Recording of type feedback |
| @@ -1215,4 +1006,177 @@ CaseClause::CaseClause(Isolate* isolate, |
| entry_id_(AstNode::GetNextId(isolate)) { |
| } |
| + |
| +AstProperties* AstConstructionVisitor::DetachAstProperties() { |
| + properties_->add_node_count(node_count_); |
| + properties_->flags()->Add(flags_); |
| + return properties_; |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitDeclaration(Declaration* node) { |
| + increase_node_count(); |
| + // TODO(jkummerow): Inlineable iff |
| + // proxy()->var()->IsStackAllocated() && fun() == NULL; |
|
fschneider
2012/02/06 14:14:29
Forgotten commented code?
Jakob Kummerow
2012/02/07 12:38:37
No, two-line comment :-)
It was intended as a remi
|
| +} |
| + |
| + |
| +#define INCREASE_NODE_COUNT(NodeType) \ |
| + void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \ |
| + increase_node_count(); \ |
| + } |
| + |
| +INCREASE_NODE_COUNT(Block) |
| +INCREASE_NODE_COUNT(ExpressionStatement) |
| +INCREASE_NODE_COUNT(EmptyStatement) |
| +INCREASE_NODE_COUNT(IfStatement) |
| +INCREASE_NODE_COUNT(ContinueStatement) |
| +INCREASE_NODE_COUNT(BreakStatement) |
| +INCREASE_NODE_COUNT(ReturnStatement) |
| +INCREASE_NODE_COUNT(Conditional) |
| +INCREASE_NODE_COUNT(Literal) |
| +INCREASE_NODE_COUNT(Assignment) |
| +INCREASE_NODE_COUNT(Throw) |
| +INCREASE_NODE_COUNT(Property) |
| +INCREASE_NODE_COUNT(UnaryOperation) |
| +INCREASE_NODE_COUNT(CountOperation) |
| +INCREASE_NODE_COUNT(BinaryOperation) |
| +INCREASE_NODE_COUNT(CompareOperation) |
| +INCREASE_NODE_COUNT(ThisFunction) |
| + |
| +#undef INCREASE_NODE_COUNT |
| + |
| + |
| +void AstConstructionVisitor::VisitWithStatement(WithStatement* node) { |
| + increase_node_count(); |
| + add_flag(kDontCrankshaft); |
| + add_flag(kDontInline); |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitSwitchStatement(SwitchStatement* node) { |
| + increase_node_count(); |
| + add_flag(kDontInline); |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitDoWhileStatement(DoWhileStatement* node) { |
| + increase_node_count(); |
| + add_flag(kDontSelfOptimize); |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitWhileStatement(WhileStatement* node) { |
| + increase_node_count(); |
| + add_flag(kDontSelfOptimize); |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitForStatement(ForStatement* node) { |
| + increase_node_count(); |
| + add_flag(kDontSelfOptimize); |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitForInStatement(ForInStatement* node) { |
| + increase_node_count(); |
| + add_flag(kDontCrankshaft); |
| + add_flag(kDontInline); |
| + add_flag(kDontSelfOptimize); |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitTryCatchStatement(TryCatchStatement* node) { |
| + increase_node_count(); |
| + add_flag(kDontCrankshaft); |
| + add_flag(kDontInline); |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitTryFinallyStatement( |
| + TryFinallyStatement* node) { |
| + increase_node_count(); |
| + add_flag(kDontCrankshaft); |
| + add_flag(kDontInline); |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitDebuggerStatement(DebuggerStatement* node) { |
| + increase_node_count(); |
| + add_flag(kDontCrankshaft); |
| + add_flag(kDontInline); |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitFunctionLiteral(FunctionLiteral* node) { |
| + increase_node_count(); |
| + add_flag(kDontInline); |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitSharedFunctionInfoLiteral( |
| + SharedFunctionInfoLiteral* node) { |
| + increase_node_count(); |
| + add_flag(kDontCrankshaft); |
| + add_flag(kDontInline); |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitVariableProxy(VariableProxy* node) { |
| + increase_node_count(); |
| + // In theory, we'd have to add: |
| + // if(node->var()->IsLookupSlot()) { add_flag(kDontInline); } |
| + // However, node->var() is usually not bound yet at VariableProxy creation |
| + // time, and LOOKUP variables only result from constructs that cannot |
| + // be inlined anyway. |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitRegExpLiteral(RegExpLiteral* node) { |
| + increase_node_count(); |
| + add_flag(kDontInline); // TODO(1322): Allow materialized literals. |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitObjectLiteral(ObjectLiteral* node) { |
| + increase_node_count(); |
| + add_flag(kDontInline); // TODO(1322): Allow materialized literals. |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitArrayLiteral(ArrayLiteral* node) { |
| + increase_node_count(); |
| + add_flag(kDontInline); // TODO(1322): Allow materialized literals. |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitCall(Call* node) { |
| + increase_node_count(); |
| + add_flag(kDontSelfOptimize); |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitCallNew(CallNew* node) { |
| + increase_node_count(); |
| + add_flag(kDontSelfOptimize); |
| +} |
| + |
| + |
| +void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) { |
| + increase_node_count(); |
| + add_flag(kDontSelfOptimize); |
| + if (node->is_jsruntime()) { |
| + // Don't try to inline JS runtime calls because we don't (currently) even |
| + // optimize them. |
| + add_flag(kDontInline); |
| + } else if (node->function()->intrinsic_type == Runtime::INLINE && |
| + (node->name()->IsEqualTo(CStrVector("_ArgumentsLength")) || |
| + node->name()->IsEqualTo(CStrVector("_Arguments")))) { |
| + // Don't inline the %_ArgumentsLength or %_Arguments because their |
| + // implementation will not work. There is no stack frame to get them |
| + // from. |
| + add_flag(kDontInline); |
| + } |
| +} |
| + |
| } } // namespace v8::internal |