Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | |
| 2 // Redistribution and use in source and binary forms, with or without | |
| 3 // modification, are permitted provided that the following conditions are | |
| 4 // met: | |
| 5 // | |
| 6 // * Redistributions of source code must retain the above copyright | |
| 7 // notice, this list of conditions and the following disclaimer. | |
| 8 // * Redistributions in binary form must reproduce the above | |
| 9 // copyright notice, this list of conditions and the following | |
| 10 // disclaimer in the documentation and/or other materials provided | |
| 11 // with the distribution. | |
| 12 // * Neither the name of Google Inc. nor the names of its | |
| 13 // contributors may be used to endorse or promote products derived | |
| 14 // from this software without specific prior written permission. | |
| 15 // | |
| 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 27 | |
| 28 #include "v8.h" | |
| 29 | |
| 30 #include "feedbackslots.h" | |
| 31 | |
| 32 #include "ast.h" | |
| 33 #include "compiler.h" | |
| 34 #include "scopes.h" | |
| 35 | |
| 36 namespace v8 { | |
| 37 namespace internal { | |
| 38 | |
| 39 #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.
| |
| 40 do { \ | |
| 41 ASSERT(!allocator.HasStackOverflow()); \ | |
| 42 call; \ | |
| 43 if (allocator.HasStackOverflow()) return false; \ | |
| 44 } while (false) | |
| 45 | |
| 46 | |
| 47 bool FeedbackSlotAllocator::Run(CompilationInfo* info) { | |
| 48 FeedbackSlotAllocator allocator(info->zone()); | |
| 49 Scope* scope = info->scope(); | |
| 50 // Handle implicit declaration of the function name in named function | |
| 51 // expressions before other declarations. | |
| 52 if (scope->is_function_scope() && scope->function() != NULL) { | |
| 53 RECURSE(allocator.VisitVariableDeclaration(scope->function())); | |
| 54 } | |
| 55 RECURSE(allocator.VisitDeclarations(scope->declarations())); | |
| 56 RECURSE(allocator.VisitStatements(info->function()->body())); | |
| 57 info->set_feedback_slots(allocator.slot_count()); | |
| 58 return true; | |
| 59 } | |
| 60 #undef RECURSE | |
| 61 | |
| 62 | |
| 63 #define RECURSE(call) \ | |
| 64 do { \ | |
| 65 ASSERT(!HasStackOverflow()); \ | |
| 66 call; \ | |
| 67 if (HasStackOverflow()) return; \ | |
| 68 } while (false) | |
| 69 | |
| 70 | |
| 71 void FeedbackSlotAllocator::DoVisitBlock(Block* stmt) { | |
| 72 RECURSE(VisitStatements(stmt->statements())); | |
| 73 } | |
| 74 | |
| 75 | |
| 76 void FeedbackSlotAllocator::DoVisitExpressionStatement( | |
| 77 ExpressionStatement* stmt) { | |
| 78 RECURSE(Visit(stmt->expression())); | |
| 79 } | |
| 80 | |
| 81 | |
| 82 void FeedbackSlotAllocator::DoVisitEmptyStatement(EmptyStatement* stmt) { | |
| 83 } | |
| 84 | |
| 85 | |
| 86 void FeedbackSlotAllocator::DoVisitIfStatement(IfStatement* stmt) { | |
| 87 RECURSE(Visit(stmt->condition())); | |
| 88 RECURSE(Visit(stmt->then_statement())); | |
| 89 RECURSE(Visit(stmt->else_statement())); | |
| 90 } | |
| 91 | |
| 92 | |
| 93 void FeedbackSlotAllocator::DoVisitContinueStatement(ContinueStatement* stmt) { | |
| 94 } | |
| 95 | |
| 96 | |
| 97 void FeedbackSlotAllocator::DoVisitBreakStatement(BreakStatement* stmt) { | |
| 98 } | |
| 99 | |
| 100 | |
| 101 void FeedbackSlotAllocator::DoVisitReturnStatement(ReturnStatement* stmt) { | |
| 102 RECURSE(Visit(stmt->expression())); | |
| 103 } | |
| 104 | |
| 105 | |
| 106 void FeedbackSlotAllocator::DoVisitWithStatement(WithStatement* stmt) { | |
| 107 RECURSE(Visit(stmt->expression())); | |
| 108 RECURSE(Visit(stmt->statement())); | |
| 109 } | |
| 110 | |
| 111 | |
| 112 void FeedbackSlotAllocator::DoVisitSwitchStatement(SwitchStatement* stmt) { | |
| 113 RECURSE(Visit(stmt->tag())); | |
| 114 | |
| 115 ZoneList<CaseClause*>* clauses = stmt->cases(); | |
| 116 for (int i = 0; i < clauses->length(); ++i) { | |
| 117 CaseClause* clause = clauses->at(i); | |
| 118 if (!clause->is_default()) { | |
| 119 Expression* label = clause->label(); | |
| 120 RECURSE(Visit(label)); | |
| 121 } | |
| 122 | |
| 123 ZoneList<Statement*>* stmts = clause->statements(); | |
| 124 RECURSE(VisitStatements(stmts)); | |
| 125 } | |
| 126 } | |
| 127 | |
| 128 | |
| 129 void FeedbackSlotAllocator::DoVisitCaseClause(CaseClause* clause) { | |
| 130 } | |
| 131 | |
| 132 | |
| 133 void FeedbackSlotAllocator::DoVisitDoWhileStatement(DoWhileStatement* stmt) { | |
| 134 RECURSE(Visit(stmt->body())); | |
| 135 RECURSE(Visit(stmt->cond())); | |
| 136 } | |
| 137 | |
| 138 | |
| 139 void FeedbackSlotAllocator::DoVisitWhileStatement(WhileStatement* stmt) { | |
| 140 RECURSE(Visit(stmt->cond())); | |
| 141 RECURSE(Visit(stmt->body())); | |
| 142 } | |
| 143 | |
| 144 | |
| 145 void FeedbackSlotAllocator::DoVisitForStatement(ForStatement* stmt) { | |
| 146 if (stmt->init() != NULL) { | |
| 147 RECURSE(Visit(stmt->init())); | |
| 148 } | |
| 149 if (stmt->cond() != NULL) { | |
| 150 RECURSE(Visit(stmt->cond())); | |
| 151 } | |
| 152 RECURSE(Visit(stmt->body())); | |
| 153 if (stmt->next() != NULL) { | |
| 154 RECURSE(Visit(stmt->next())); | |
| 155 } | |
| 156 } | |
| 157 | |
| 158 | |
| 159 void FeedbackSlotAllocator::DoVisitForInStatement(ForInStatement* stmt) { | |
| 160 RECURSE(Visit(stmt->enumerable())); | |
| 161 RECURSE(Visit(stmt->body())); | |
| 162 } | |
| 163 | |
| 164 | |
| 165 void FeedbackSlotAllocator::DoVisitForOfStatement(ForOfStatement* stmt) { | |
| 166 RECURSE(Visit(stmt->iterable())); | |
| 167 RECURSE(Visit(stmt->body())); | |
| 168 } | |
| 169 | |
| 170 | |
| 171 void FeedbackSlotAllocator::DoVisitTryCatchStatement(TryCatchStatement* stmt) { | |
| 172 RECURSE(Visit(stmt->try_block())); | |
| 173 RECURSE(Visit(stmt->catch_block())); | |
| 174 } | |
| 175 | |
| 176 | |
| 177 void FeedbackSlotAllocator::DoVisitTryFinallyStatement( | |
| 178 TryFinallyStatement* stmt) { | |
| 179 RECURSE(Visit(stmt->try_block())); | |
| 180 RECURSE(Visit(stmt->finally_block())); | |
| 181 } | |
| 182 | |
| 183 | |
| 184 void FeedbackSlotAllocator::DoVisitDebuggerStatement(DebuggerStatement* stmt) { | |
| 185 } | |
| 186 | |
| 187 | |
| 188 void FeedbackSlotAllocator::DoVisitFunctionLiteral(FunctionLiteral* expr) { | |
| 189 } | |
| 190 | |
| 191 | |
| 192 void FeedbackSlotAllocator::DoVisitNativeFunctionLiteral( | |
| 193 NativeFunctionLiteral* expr) { | |
| 194 } | |
| 195 | |
| 196 | |
| 197 void FeedbackSlotAllocator::DoVisitConditional(Conditional* expr) { | |
| 198 RECURSE(Visit(expr->condition())); | |
| 199 RECURSE(Visit(expr->then_expression())); | |
| 200 RECURSE(Visit(expr->else_expression())); | |
| 201 } | |
| 202 | |
| 203 | |
| 204 void FeedbackSlotAllocator::DoVisitVariableProxy(VariableProxy* expr) { | |
| 205 } | |
| 206 | |
| 207 | |
| 208 void FeedbackSlotAllocator::DoVisitLiteral(Literal* expr) { | |
| 209 } | |
| 210 | |
| 211 | |
| 212 void FeedbackSlotAllocator::DoVisitRegExpLiteral(RegExpLiteral* expr) { | |
| 213 } | |
| 214 | |
| 215 | |
| 216 void FeedbackSlotAllocator::DoVisitObjectLiteral(ObjectLiteral* expr) { | |
| 217 ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); | |
| 218 for (int i = 0; i < properties->length(); ++i) { | |
| 219 ObjectLiteral::Property* prop = properties->at(i); | |
| 220 RECURSE(Visit(prop->value())); | |
| 221 } | |
| 222 } | |
| 223 | |
| 224 | |
| 225 void FeedbackSlotAllocator::DoVisitArrayLiteral(ArrayLiteral* expr) { | |
| 226 ZoneList<Expression*>* values = expr->values(); | |
| 227 for (int i = 0; i < values->length(); ++i) { | |
| 228 Expression* value = values->at(i); | |
| 229 RECURSE(Visit(value)); | |
| 230 } | |
| 231 } | |
| 232 | |
| 233 | |
| 234 void FeedbackSlotAllocator::DoVisitAssignment(Assignment* expr) { | |
| 235 Expression* rhs = | |
| 236 expr->is_compound() ? expr->binary_operation() : expr->value(); | |
| 237 RECURSE(Visit(expr->target())); | |
| 238 RECURSE(Visit(rhs)); | |
| 239 } | |
| 240 | |
| 241 | |
| 242 void FeedbackSlotAllocator::DoVisitYield(Yield* expr) { | |
| 243 RECURSE(Visit(expr->generator_object())); | |
| 244 RECURSE(Visit(expr->expression())); | |
| 245 } | |
| 246 | |
| 247 | |
| 248 void FeedbackSlotAllocator::DoVisitThrow(Throw* expr) { | |
| 249 RECURSE(Visit(expr->exception())); | |
| 250 } | |
| 251 | |
| 252 | |
| 253 void FeedbackSlotAllocator::DoVisitProperty(Property* expr) { | |
| 254 RECURSE(Visit(expr->obj())); | |
| 255 RECURSE(Visit(expr->key())); | |
| 256 } | |
| 257 | |
| 258 | |
| 259 void FeedbackSlotAllocator::DoVisitCall(Call* expr) { | |
| 260 RECURSE(Visit(expr->expression())); | |
| 261 ZoneList<Expression*>* args = expr->arguments(); | |
| 262 for (int i = 0; i < args->length(); ++i) { | |
| 263 Expression* arg = args->at(i); | |
| 264 RECURSE(Visit(arg)); | |
| 265 } | |
| 266 } | |
| 267 | |
| 268 | |
| 269 void FeedbackSlotAllocator::DoVisitCallNew(CallNew* expr) { | |
| 270 RECURSE(Visit(expr->expression())); | |
| 271 ZoneList<Expression*>* args = expr->arguments(); | |
| 272 for (int i = 0; i < args->length(); ++i) { | |
| 273 Expression* arg = args->at(i); | |
| 274 RECURSE(Visit(arg)); | |
| 275 } | |
| 276 } | |
| 277 | |
| 278 | |
| 279 void FeedbackSlotAllocator::DoVisitCallRuntime(CallRuntime* expr) { | |
| 280 ZoneList<Expression*>* args = expr->arguments(); | |
| 281 for (int i = 0; i < args->length(); ++i) { | |
| 282 Expression* arg = args->at(i); | |
| 283 RECURSE(Visit(arg)); | |
| 284 } | |
| 285 } | |
| 286 | |
| 287 | |
| 288 void FeedbackSlotAllocator::DoVisitUnaryOperation(UnaryOperation* expr) { | |
| 289 RECURSE(Visit(expr->expression())); | |
| 290 } | |
| 291 | |
| 292 | |
| 293 void FeedbackSlotAllocator::DoVisitCountOperation(CountOperation* expr) { | |
| 294 RECURSE(Visit(expr->expression())); | |
| 295 } | |
| 296 | |
| 297 | |
| 298 void FeedbackSlotAllocator::DoVisitBinaryOperation(BinaryOperation* expr) { | |
| 299 RECURSE(Visit(expr->left())); | |
| 300 RECURSE(Visit(expr->right())); | |
| 301 } | |
| 302 | |
| 303 | |
| 304 void FeedbackSlotAllocator::DoVisitCompareOperation(CompareOperation* expr) { | |
| 305 RECURSE(Visit(expr->left())); | |
| 306 RECURSE(Visit(expr->right())); | |
| 307 } | |
| 308 | |
| 309 | |
| 310 void FeedbackSlotAllocator::DoVisitThisFunction(ThisFunction* expr) { | |
| 311 } | |
| 312 | |
| 313 | |
| 314 void FeedbackSlotAllocator::DoVisitVariableDeclaration( | |
| 315 VariableDeclaration* declaration) { | |
| 316 } | |
| 317 | |
| 318 | |
| 319 void FeedbackSlotAllocator::DoVisitFunctionDeclaration( | |
| 320 FunctionDeclaration* declaration) { | |
| 321 RECURSE(Visit(declaration->fun())); | |
| 322 } | |
| 323 | |
| 324 | |
| 325 void FeedbackSlotAllocator::DoVisitModuleDeclaration( | |
| 326 ModuleDeclaration* declaration) { | |
| 327 RECURSE(Visit(declaration->module())); | |
| 328 } | |
| 329 | |
| 330 | |
| 331 void FeedbackSlotAllocator::DoVisitImportDeclaration( | |
| 332 ImportDeclaration* declaration) { | |
| 333 RECURSE(Visit(declaration->module())); | |
| 334 } | |
| 335 | |
| 336 | |
| 337 void FeedbackSlotAllocator::DoVisitExportDeclaration( | |
| 338 ExportDeclaration* declaration) { | |
| 339 } | |
| 340 | |
| 341 | |
| 342 void FeedbackSlotAllocator::DoVisitModuleLiteral(ModuleLiteral* module) { | |
| 343 RECURSE(Visit(module->body())); | |
| 344 } | |
| 345 | |
| 346 | |
| 347 void FeedbackSlotAllocator::DoVisitModuleVariable(ModuleVariable* module) { | |
| 348 } | |
| 349 | |
| 350 | |
| 351 void FeedbackSlotAllocator::DoVisitModulePath(ModulePath* module) { | |
| 352 RECURSE(Visit(module->module())); | |
| 353 } | |
| 354 | |
| 355 | |
| 356 void FeedbackSlotAllocator::DoVisitModuleUrl(ModuleUrl* module) { | |
| 357 } | |
| 358 | |
| 359 | |
| 360 void FeedbackSlotAllocator::DoVisitModuleStatement(ModuleStatement* stmt) { | |
| 361 RECURSE(Visit(stmt->body())); | |
| 362 } | |
| 363 | |
| 364 | |
| 365 } } // namespace v8::internal | |
| OLD | NEW |