Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Unified Diff: src/ast.cc

Issue 9221011: Collect AstNode type information (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/ast.h ('K') | « src/ast.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ast.cc
diff --git a/src/ast.cc b/src/ast.cc
index 2e26999c8cf177d4383d9429f3f51416e4d2d78a..affa704e906c280a049e2b3cd7c58d939de9b1c9 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -174,6 +174,24 @@ LanguageMode FunctionLiteral::language_mode() const {
}
+bool FunctionLiteral::ShouldSelfOptimize() {
+ AstNodeType::Flag types = 0;
+ int node_count = 0;
+ CollectInfo(&types, &node_count);
+ return (types & (AstNodeType::kContainsBackEdgesMask |
+ AstNodeType::kContainsCallsMask |
+ AstNodeType::kPreventsOptimizationMask)) == 0;
+}
+
+
+int FunctionLiteral::AstNodeCount() {
+ AstNodeType::Flag types = 0;
+ int node_count = 0;
+ CollectInfo(&types, &node_count);
+ return node_count;
+}
+
+
ObjectLiteral::Property::Property(Literal* key, Expression* value) {
emit_store_ = true;
key_ = key;
@@ -426,6 +444,13 @@ bool Declaration::IsInlineable() const {
}
+void Declaration::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ proxy()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
bool TargetCollector::IsInlineable() const {
UNREACHABLE();
return false;
@@ -437,28 +462,72 @@ bool ForInStatement::IsInlineable() const {
}
+void ForInStatement::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kForInStatementMask;
+ each()->CollectInfo(flags, node_count);
+ enumerable()->CollectInfo(flags, node_count);
+ body()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
bool WithStatement::IsInlineable() const {
return false;
}
+void WithStatement::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kWithStatementMask;
+ expression()->CollectInfo(flags, node_count);
+ statement()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
bool SwitchStatement::IsInlineable() const {
return false;
}
+void SwitchStatement::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kSwitchStatementMask;
+ tag()->CollectInfo(flags, node_count);
+ for (int i = 0; i < cases()->length(); ++i) {
+ CaseClause* clause(cases()->at(i));
+ if (!clause->is_default()) {
+ clause->label()->CollectInfo(flags, node_count);
+ }
+ for (int j = 0; j < clause->statements()->length(); ++j) {
+ clause->statements()->at(j)->CollectInfo(flags, node_count);
+ }
+ }
+ *node_count += 1;
+}
+
+
bool TryStatement::IsInlineable() const {
return false;
}
-bool TryCatchStatement::IsInlineable() const {
- return false;
+void TryCatchStatement::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kTryCatchStatementMask;
+ try_block()->CollectInfo(flags, node_count);
+ catch_block()->CollectInfo(flags, node_count);
+ *node_count += 1;
}
-bool TryFinallyStatement::IsInlineable() const {
- return false;
+void TryFinallyStatement::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kTryFinallyStatementMask;
+ try_block()->CollectInfo(flags, node_count);
+ finally_block()->CollectInfo(flags, node_count);
+ *node_count += 1;
}
@@ -467,33 +536,106 @@ bool DebuggerStatement::IsInlineable() const {
}
+void DebuggerStatement::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kDebuggerStatementMask;
+ *node_count += 1;
+}
+
+
bool Throw::IsInlineable() const {
return exception()->IsInlineable();
}
+void Throw::CollectInfo(AstNodeType::Flag* flags, int* node_count) const {
+ *flags |= AstNodeType::kThrowMask;
+ exception()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
bool MaterializedLiteral::IsInlineable() const {
// TODO(1322): Allow materialized literals.
return false;
}
+void ObjectLiteral::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kObjectLiteralMask;
+ for (int i = 0; i < properties()->length(); ++i) {
+ properties()->at(i)->key()->CollectInfo(flags, node_count);
+ properties()->at(i)->value()->CollectInfo(flags, node_count);
+ }
+ *node_count += 1;
+}
+
+
+void RegExpLiteral::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kRegExpLiteralMask;
+ *node_count += 1;
+}
+
+
+void ArrayLiteral::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kArrayLiteralMask;
+ for (int i = 0; i < values()->length(); ++i) {
+ values()->at(i)->CollectInfo(flags, node_count);
+ }
+ *node_count += 1;
+}
+
+
bool FunctionLiteral::IsInlineable() const {
// TODO(1322): Allow materialized literals.
return false;
}
+void FunctionLiteral::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kFunctionLiteralMask;
+ if (scope()->declarations() != NULL) {
+ for (int i = 0; i < scope()->declarations()->length(); ++i) {
+ scope()->declarations()->at(i)->CollectInfo(flags, node_count);
+ }
+ }
+ if (body() != NULL) {
+ for (int i = 0; i < body()->length(); ++i) {
+ body()->at(i)->CollectInfo(flags, node_count);
+ }
+ }
+ *node_count += 1;
+}
+
+
bool ThisFunction::IsInlineable() const {
return true;
}
+void ThisFunction::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kThisFunctionMask;
+ *node_count += 1;
+}
+
+
bool SharedFunctionInfoLiteral::IsInlineable() const {
return false;
}
+void SharedFunctionInfoLiteral::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kSharedFunctionInfoLiteralMask;
+ *node_count += 1;
+}
+
+
bool ForStatement::IsInlineable() const {
return (init() == NULL || init()->IsInlineable())
&& (cond() == NULL || cond()->IsInlineable())
@@ -502,33 +644,82 @@ bool ForStatement::IsInlineable() const {
}
+void ForStatement::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kForStatementMask;
+ if (init() != NULL) init()->CollectInfo(flags, node_count);
+ if (cond() != NULL) cond()->CollectInfo(flags, node_count);
+ if (next() != NULL) next()->CollectInfo(flags, node_count);
+ body()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
bool WhileStatement::IsInlineable() const {
return cond()->IsInlineable()
&& body()->IsInlineable();
}
+void WhileStatement::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kWhileStatementMask;
+ cond()->CollectInfo(flags, node_count);
+ body()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
bool DoWhileStatement::IsInlineable() const {
return cond()->IsInlineable()
&& body()->IsInlineable();
}
+void DoWhileStatement::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kDoWhileStatementMask;
+ cond()->CollectInfo(flags, node_count);
+ body()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
bool ContinueStatement::IsInlineable() const {
return true;
}
+void ContinueStatement::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kContinueStatementMask;
+ *node_count += 1;
+}
+
+
bool BreakStatement::IsInlineable() const {
return true;
}
+void BreakStatement::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kBreakStatementMask;
+ *node_count += 1;
+}
+
+
bool EmptyStatement::IsInlineable() const {
return true;
}
+void EmptyStatement::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ // Nothing to see here, move on.
+}
+
+
bool Literal::IsInlineable() const {
return true;
}
@@ -543,11 +734,25 @@ bool Block::IsInlineable() const {
}
+void Block::CollectInfo(AstNodeType::Flag* flags, int* node_count) const {
+ for (int i = 0; i < statements_.length(); ++i) {
+ statements_[i]->CollectInfo(flags, node_count);
+ }
+ *node_count += 1;
+}
+
+
bool ExpressionStatement::IsInlineable() const {
return expression()->IsInlineable();
}
+void ExpressionStatement::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ expression()->CollectInfo(flags, node_count);
+}
+
+
bool IfStatement::IsInlineable() const {
return condition()->IsInlineable()
&& then_statement()->IsInlineable()
@@ -555,17 +760,46 @@ bool IfStatement::IsInlineable() const {
}
+void IfStatement::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kIfStatementMask;
+ condition()->CollectInfo(flags, node_count);
+ then_statement()->CollectInfo(flags, node_count);
+ else_statement()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
+
bool ReturnStatement::IsInlineable() const {
return expression()->IsInlineable();
}
+void ReturnStatement::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kReturnStatementMask;
+ expression()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
bool Conditional::IsInlineable() const {
return condition()->IsInlineable() && then_expression()->IsInlineable() &&
else_expression()->IsInlineable();
}
+void Conditional::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kConditionalMask;
+ condition()->CollectInfo(flags, node_count);
+ then_expression()->CollectInfo(flags, node_count);
+ else_expression()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
bool VariableProxy::IsInlineable() const {
return var()->IsUnallocated()
|| var()->IsStackAllocated()
@@ -578,11 +812,28 @@ bool Assignment::IsInlineable() const {
}
+void Assignment::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ target()->CollectInfo(flags, node_count);
+ value()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
bool Property::IsInlineable() const {
return obj()->IsInlineable() && key()->IsInlineable();
}
+void Property::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ *flags |= AstNodeType::kPropertyMask;
+ obj()->CollectInfo(flags, node_count);
+ key()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
bool Call::IsInlineable() const {
if (!expression()->IsInlineable()) return false;
const int count = arguments()->length();
@@ -593,6 +844,16 @@ bool Call::IsInlineable() const {
}
+void Call::CollectInfo(AstNodeType::Flag* flags, int* node_count) const {
+ *flags |= AstNodeType::kCallMask;
+ expression()->CollectInfo(flags, node_count);
+ for (int i = 0; i < arguments()->length(); ++i) {
+ arguments()->at(i)->CollectInfo(flags, node_count);
+ }
+ *node_count += 1;
+}
+
+
bool CallNew::IsInlineable() const {
if (!expression()->IsInlineable()) return false;
const int count = arguments()->length();
@@ -603,6 +864,16 @@ bool CallNew::IsInlineable() const {
}
+void CallNew::CollectInfo(AstNodeType::Flag* flags, int* node_count) const {
+ *flags |= AstNodeType::kCallNewMask;
+ expression()->CollectInfo(flags, node_count);
+ for (int i = 0; i < arguments()->length(); ++i) {
+ arguments()->at(i)->CollectInfo(flags, node_count);
+ }
+ *node_count += 1;
+}
+
+
bool CallRuntime::IsInlineable() const {
// Don't try to inline JS runtime calls because we don't (currently) even
// optimize them.
@@ -623,26 +894,65 @@ bool CallRuntime::IsInlineable() const {
}
+void CallRuntime::CollectInfo(AstNodeType::Flag* flags, int* node_count) const {
+ *flags |= AstNodeType::kCallRuntimeMask;
+ for (int i = 0; i < arguments()->length(); ++i) {
+ arguments()->at(i)->CollectInfo(flags, node_count);
+ }
+ *node_count += 1;
+}
+
+
bool UnaryOperation::IsInlineable() const {
return expression()->IsInlineable();
}
+void UnaryOperation::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ expression()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
bool BinaryOperation::IsInlineable() const {
return left()->IsInlineable() && right()->IsInlineable();
}
+void BinaryOperation::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ left()->CollectInfo(flags, node_count);
+ right()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
bool CompareOperation::IsInlineable() const {
return left()->IsInlineable() && right()->IsInlineable();
}
+void CompareOperation::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ left()->CollectInfo(flags, node_count);
+ right()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
bool CountOperation::IsInlineable() const {
return expression()->IsInlineable();
}
+void CountOperation::CollectInfo(AstNodeType::Flag* flags,
+ int* node_count) const {
+ expression()->CollectInfo(flags, node_count);
+ *node_count += 1;
+}
+
+
// ----------------------------------------------------------------------------
// Recording of type feedback
« src/ast.h ('K') | « src/ast.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698