Chromium Code Reviews| 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 |