Index: src/feedbackslots.cc |
diff --git a/src/feedbackslots.cc b/src/feedbackslots.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9fa02db2014e934838ba82134891e001ba24ec3c |
--- /dev/null |
+++ b/src/feedbackslots.cc |
@@ -0,0 +1,365 @@ |
+// Copyright 2014 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: |
+// |
+// * Redistributions of source code must retain the above copyright |
+// notice, this list of conditions and the following disclaimer. |
+// * Redistributions in binary form must reproduce the above |
+// copyright notice, this list of conditions and the following |
+// disclaimer in the documentation and/or other materials provided |
+// with the distribution. |
+// * Neither the name of Google Inc. nor the names of its |
+// contributors may be used to endorse or promote products derived |
+// from this software without specific prior written permission. |
+// |
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+ |
+#include "v8.h" |
+ |
+#include "feedbackslots.h" |
+ |
+#include "ast.h" |
+#include "compiler.h" |
+#include "scopes.h" |
+ |
+namespace v8 { |
+namespace internal { |
+ |
+#define RECURSE(call) \ |
danno
2014/01/28 08:27:17
Here and below, this seems like a lot of boilerpla
mvstanton
2014/01/30 15:13:41
Done.
|
+ do { \ |
+ ASSERT(!allocator.HasStackOverflow()); \ |
+ call; \ |
+ if (allocator.HasStackOverflow()) return false; \ |
+ } while (false) |
+ |
+ |
+bool FeedbackSlotAllocator::Run(CompilationInfo* info) { |
+ FeedbackSlotAllocator allocator(info->zone()); |
+ Scope* scope = info->scope(); |
+ // Handle implicit declaration of the function name in named function |
+ // expressions before other declarations. |
+ if (scope->is_function_scope() && scope->function() != NULL) { |
+ RECURSE(allocator.VisitVariableDeclaration(scope->function())); |
+ } |
+ RECURSE(allocator.VisitDeclarations(scope->declarations())); |
+ RECURSE(allocator.VisitStatements(info->function()->body())); |
+ info->set_feedback_slots(allocator.slot_count()); |
+ return true; |
+} |
+#undef RECURSE |
+ |
+ |
+#define RECURSE(call) \ |
+ do { \ |
+ ASSERT(!HasStackOverflow()); \ |
+ call; \ |
+ if (HasStackOverflow()) return; \ |
+ } while (false) |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitBlock(Block* stmt) { |
+ RECURSE(VisitStatements(stmt->statements())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitExpressionStatement( |
+ ExpressionStatement* stmt) { |
+ RECURSE(Visit(stmt->expression())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitEmptyStatement(EmptyStatement* stmt) { |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitIfStatement(IfStatement* stmt) { |
+ RECURSE(Visit(stmt->condition())); |
+ RECURSE(Visit(stmt->then_statement())); |
+ RECURSE(Visit(stmt->else_statement())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitContinueStatement(ContinueStatement* stmt) { |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitBreakStatement(BreakStatement* stmt) { |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitReturnStatement(ReturnStatement* stmt) { |
+ RECURSE(Visit(stmt->expression())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitWithStatement(WithStatement* stmt) { |
+ RECURSE(Visit(stmt->expression())); |
+ RECURSE(Visit(stmt->statement())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitSwitchStatement(SwitchStatement* stmt) { |
+ RECURSE(Visit(stmt->tag())); |
+ |
+ ZoneList<CaseClause*>* clauses = stmt->cases(); |
+ for (int i = 0; i < clauses->length(); ++i) { |
+ CaseClause* clause = clauses->at(i); |
+ if (!clause->is_default()) { |
+ Expression* label = clause->label(); |
+ RECURSE(Visit(label)); |
+ } |
+ |
+ ZoneList<Statement*>* stmts = clause->statements(); |
+ RECURSE(VisitStatements(stmts)); |
+ } |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitCaseClause(CaseClause* clause) { |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitDoWhileStatement(DoWhileStatement* stmt) { |
+ RECURSE(Visit(stmt->body())); |
+ RECURSE(Visit(stmt->cond())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitWhileStatement(WhileStatement* stmt) { |
+ RECURSE(Visit(stmt->cond())); |
+ RECURSE(Visit(stmt->body())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitForStatement(ForStatement* stmt) { |
+ if (stmt->init() != NULL) { |
+ RECURSE(Visit(stmt->init())); |
+ } |
+ if (stmt->cond() != NULL) { |
+ RECURSE(Visit(stmt->cond())); |
+ } |
+ RECURSE(Visit(stmt->body())); |
+ if (stmt->next() != NULL) { |
+ RECURSE(Visit(stmt->next())); |
+ } |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitForInStatement(ForInStatement* stmt) { |
+ RECURSE(Visit(stmt->enumerable())); |
+ RECURSE(Visit(stmt->body())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitForOfStatement(ForOfStatement* stmt) { |
+ RECURSE(Visit(stmt->iterable())); |
+ RECURSE(Visit(stmt->body())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitTryCatchStatement(TryCatchStatement* stmt) { |
+ RECURSE(Visit(stmt->try_block())); |
+ RECURSE(Visit(stmt->catch_block())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitTryFinallyStatement( |
+ TryFinallyStatement* stmt) { |
+ RECURSE(Visit(stmt->try_block())); |
+ RECURSE(Visit(stmt->finally_block())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitDebuggerStatement(DebuggerStatement* stmt) { |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitFunctionLiteral(FunctionLiteral* expr) { |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitNativeFunctionLiteral( |
+ NativeFunctionLiteral* expr) { |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitConditional(Conditional* expr) { |
+ RECURSE(Visit(expr->condition())); |
+ RECURSE(Visit(expr->then_expression())); |
+ RECURSE(Visit(expr->else_expression())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitVariableProxy(VariableProxy* expr) { |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitLiteral(Literal* expr) { |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitRegExpLiteral(RegExpLiteral* expr) { |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitObjectLiteral(ObjectLiteral* expr) { |
+ ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); |
+ for (int i = 0; i < properties->length(); ++i) { |
+ ObjectLiteral::Property* prop = properties->at(i); |
+ RECURSE(Visit(prop->value())); |
+ } |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitArrayLiteral(ArrayLiteral* expr) { |
+ ZoneList<Expression*>* values = expr->values(); |
+ for (int i = 0; i < values->length(); ++i) { |
+ Expression* value = values->at(i); |
+ RECURSE(Visit(value)); |
+ } |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitAssignment(Assignment* expr) { |
+ Expression* rhs = |
+ expr->is_compound() ? expr->binary_operation() : expr->value(); |
+ RECURSE(Visit(expr->target())); |
+ RECURSE(Visit(rhs)); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitYield(Yield* expr) { |
+ RECURSE(Visit(expr->generator_object())); |
+ RECURSE(Visit(expr->expression())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitThrow(Throw* expr) { |
+ RECURSE(Visit(expr->exception())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitProperty(Property* expr) { |
+ RECURSE(Visit(expr->obj())); |
+ RECURSE(Visit(expr->key())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitCall(Call* expr) { |
+ RECURSE(Visit(expr->expression())); |
+ ZoneList<Expression*>* args = expr->arguments(); |
+ for (int i = 0; i < args->length(); ++i) { |
+ Expression* arg = args->at(i); |
+ RECURSE(Visit(arg)); |
+ } |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitCallNew(CallNew* expr) { |
+ RECURSE(Visit(expr->expression())); |
+ ZoneList<Expression*>* args = expr->arguments(); |
+ for (int i = 0; i < args->length(); ++i) { |
+ Expression* arg = args->at(i); |
+ RECURSE(Visit(arg)); |
+ } |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitCallRuntime(CallRuntime* expr) { |
+ ZoneList<Expression*>* args = expr->arguments(); |
+ for (int i = 0; i < args->length(); ++i) { |
+ Expression* arg = args->at(i); |
+ RECURSE(Visit(arg)); |
+ } |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitUnaryOperation(UnaryOperation* expr) { |
+ RECURSE(Visit(expr->expression())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitCountOperation(CountOperation* expr) { |
+ RECURSE(Visit(expr->expression())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitBinaryOperation(BinaryOperation* expr) { |
+ RECURSE(Visit(expr->left())); |
+ RECURSE(Visit(expr->right())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitCompareOperation(CompareOperation* expr) { |
+ RECURSE(Visit(expr->left())); |
+ RECURSE(Visit(expr->right())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitThisFunction(ThisFunction* expr) { |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitVariableDeclaration( |
+ VariableDeclaration* declaration) { |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitFunctionDeclaration( |
+ FunctionDeclaration* declaration) { |
+ RECURSE(Visit(declaration->fun())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitModuleDeclaration( |
+ ModuleDeclaration* declaration) { |
+ RECURSE(Visit(declaration->module())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitImportDeclaration( |
+ ImportDeclaration* declaration) { |
+ RECURSE(Visit(declaration->module())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitExportDeclaration( |
+ ExportDeclaration* declaration) { |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitModuleLiteral(ModuleLiteral* module) { |
+ RECURSE(Visit(module->body())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitModuleVariable(ModuleVariable* module) { |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitModulePath(ModulePath* module) { |
+ RECURSE(Visit(module->module())); |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitModuleUrl(ModuleUrl* module) { |
+} |
+ |
+ |
+void FeedbackSlotAllocator::DoVisitModuleStatement(ModuleStatement* stmt) { |
+ RECURSE(Visit(stmt->body())); |
+} |
+ |
+ |
+} } // namespace v8::internal |