| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 // The desired expression context of the currently visited expression. | 76 // The desired expression context of the currently visited expression. |
| 77 Expression::Context context_; | 77 Expression::Context context_; |
| 78 | 78 |
| 79 DISALLOW_COPY_AND_ASSIGN(CodeGenSelector); | 79 DISALLOW_COPY_AND_ASSIGN(CodeGenSelector); |
| 80 }; | 80 }; |
| 81 | 81 |
| 82 | 82 |
| 83 static Handle<Code> MakeCode(FunctionLiteral* literal, | 83 static Handle<Code> MakeCode(FunctionLiteral* literal, |
| 84 Handle<Script> script, | 84 Handle<Script> script, |
| 85 Handle<Context> context, | 85 Handle<Context> context, |
| 86 bool is_eval) { | 86 bool is_eval, |
| 87 Handle<SharedFunctionInfo> shared) { |
| 87 ASSERT(literal != NULL); | 88 ASSERT(literal != NULL); |
| 88 | 89 |
| 89 // Rewrite the AST by introducing .result assignments where needed. | 90 // Rewrite the AST by introducing .result assignments where needed. |
| 90 if (!Rewriter::Process(literal) || !AnalyzeVariableUsage(literal)) { | 91 if (!Rewriter::Process(literal) || !AnalyzeVariableUsage(literal)) { |
| 91 // Signal a stack overflow by returning a null handle. The stack | 92 // Signal a stack overflow by returning a null handle. The stack |
| 92 // overflow exception will be thrown by the caller. | 93 // overflow exception will be thrown by the caller. |
| 93 return Handle<Code>::null(); | 94 return Handle<Code>::null(); |
| 94 } | 95 } |
| 95 | 96 |
| 96 { | 97 { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 113 | 114 |
| 114 // Optimize the AST. | 115 // Optimize the AST. |
| 115 if (!Rewriter::Optimize(literal)) { | 116 if (!Rewriter::Optimize(literal)) { |
| 116 // Signal a stack overflow by returning a null handle. The stack | 117 // Signal a stack overflow by returning a null handle. The stack |
| 117 // overflow exception will be thrown by the caller. | 118 // overflow exception will be thrown by the caller. |
| 118 return Handle<Code>::null(); | 119 return Handle<Code>::null(); |
| 119 } | 120 } |
| 120 | 121 |
| 121 // Generate code and return it. | 122 // Generate code and return it. |
| 122 if (FLAG_fast_compiler) { | 123 if (FLAG_fast_compiler) { |
| 123 CodeGenSelector selector; | 124 // If there is no shared function info, try the fast code |
| 124 CodeGenSelector::CodeGenTag code_gen = selector.Select(literal); | 125 // generator for code in the global scope. Otherwise obey the |
| 125 if (code_gen == CodeGenSelector::FAST) { | 126 // explicit hint in the shared function info. |
| 126 return FastCodeGenerator::MakeCode(literal, script, is_eval); | 127 if (shared.is_null() && !literal->scope()->is_global_scope()) { |
| 128 if (FLAG_trace_bailout) PrintF("Non-global scope\n"); |
| 129 } else if (!shared.is_null() && !shared->try_fast_codegen()) { |
| 130 if (FLAG_trace_bailout) PrintF("No hint to try fast\n"); |
| 131 } else { |
| 132 CodeGenSelector selector; |
| 133 CodeGenSelector::CodeGenTag code_gen = selector.Select(literal); |
| 134 if (code_gen == CodeGenSelector::FAST) { |
| 135 return FastCodeGenerator::MakeCode(literal, script, is_eval); |
| 136 } |
| 137 ASSERT(code_gen == CodeGenSelector::NORMAL); |
| 127 } | 138 } |
| 128 ASSERT(code_gen == CodeGenSelector::NORMAL); | |
| 129 } | 139 } |
| 130 return CodeGenerator::MakeCode(literal, script, is_eval); | 140 return CodeGenerator::MakeCode(literal, script, is_eval); |
| 131 } | 141 } |
| 132 | 142 |
| 133 | 143 |
| 134 static bool IsValidJSON(FunctionLiteral* lit) { | 144 static bool IsValidJSON(FunctionLiteral* lit) { |
| 135 if (lit->body()->length() != 1) | 145 if (lit->body()->length() != 1) |
| 136 return false; | 146 return false; |
| 137 Statement* stmt = lit->body()->at(0); | 147 Statement* stmt = lit->body()->at(0); |
| 138 if (stmt->AsExpressionStatement() == NULL) | 148 if (stmt->AsExpressionStatement() == NULL) |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 | 213 |
| 204 // Measure how long it takes to do the compilation; only take the | 214 // Measure how long it takes to do the compilation; only take the |
| 205 // rest of the function into account to avoid overlap with the | 215 // rest of the function into account to avoid overlap with the |
| 206 // parsing statistics. | 216 // parsing statistics. |
| 207 HistogramTimer* rate = is_eval | 217 HistogramTimer* rate = is_eval |
| 208 ? &Counters::compile_eval | 218 ? &Counters::compile_eval |
| 209 : &Counters::compile; | 219 : &Counters::compile; |
| 210 HistogramTimerScope timer(rate); | 220 HistogramTimerScope timer(rate); |
| 211 | 221 |
| 212 // Compile the code. | 222 // Compile the code. |
| 213 Handle<Code> code = MakeCode(lit, script, context, is_eval); | 223 Handle<Code> code = MakeCode(lit, script, context, is_eval, |
| 224 Handle<SharedFunctionInfo>::null()); |
| 214 | 225 |
| 215 // Check for stack-overflow exceptions. | 226 // Check for stack-overflow exceptions. |
| 216 if (code.is_null()) { | 227 if (code.is_null()) { |
| 217 Top::StackOverflow(); | 228 Top::StackOverflow(); |
| 218 return Handle<JSFunction>::null(); | 229 return Handle<JSFunction>::null(); |
| 219 } | 230 } |
| 220 | 231 |
| 221 #if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT | 232 #if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT |
| 222 // Log the code generation for the script. Check explicit whether logging is | 233 // Log the code generation for the script. Check explicit whether logging is |
| 223 // to avoid allocating when not required. | 234 // to avoid allocating when not required. |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 | 415 |
| 405 // Update the loop nesting in the function literal. | 416 // Update the loop nesting in the function literal. |
| 406 lit->set_loop_nesting(loop_nesting); | 417 lit->set_loop_nesting(loop_nesting); |
| 407 | 418 |
| 408 // Measure how long it takes to do the lazy compilation; only take | 419 // Measure how long it takes to do the lazy compilation; only take |
| 409 // the rest of the function into account to avoid overlap with the | 420 // the rest of the function into account to avoid overlap with the |
| 410 // lazy parsing statistics. | 421 // lazy parsing statistics. |
| 411 HistogramTimerScope timer(&Counters::compile_lazy); | 422 HistogramTimerScope timer(&Counters::compile_lazy); |
| 412 | 423 |
| 413 // Compile the code. | 424 // Compile the code. |
| 414 Handle<Code> code = MakeCode(lit, script, Handle<Context>::null(), false); | 425 Handle<Code> code = MakeCode(lit, script, Handle<Context>::null(), false, |
| 426 shared); |
| 415 | 427 |
| 416 // Check for stack-overflow exception. | 428 // Check for stack-overflow exception. |
| 417 if (code.is_null()) { | 429 if (code.is_null()) { |
| 418 Top::StackOverflow(); | 430 Top::StackOverflow(); |
| 419 return false; | 431 return false; |
| 420 } | 432 } |
| 421 | 433 |
| 422 #if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT | 434 #if defined ENABLE_LOGGING_AND_PROFILING || defined ENABLE_OPROFILE_AGENT |
| 423 // Log the code generation. If source information is available include script | 435 // Log the code generation. If source information is available include script |
| 424 // name and line number. Check explicit whether logging is enabled as finding | 436 // name and line number. Check explicit whether logging is enabled as finding |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 *lit->this_property_assignments()); | 470 *lit->this_property_assignments()); |
| 459 | 471 |
| 460 // Check the function has compiled code. | 472 // Check the function has compiled code. |
| 461 ASSERT(shared->is_compiled()); | 473 ASSERT(shared->is_compiled()); |
| 462 return true; | 474 return true; |
| 463 } | 475 } |
| 464 | 476 |
| 465 | 477 |
| 466 CodeGenSelector::CodeGenTag CodeGenSelector::Select(FunctionLiteral* fun) { | 478 CodeGenSelector::CodeGenTag CodeGenSelector::Select(FunctionLiteral* fun) { |
| 467 Scope* scope = fun->scope(); | 479 Scope* scope = fun->scope(); |
| 468 | 480 if (scope->num_heap_slots() != 0) { |
| 469 if (!scope->is_global_scope()) { | 481 if (FLAG_trace_bailout) PrintF("function has context slots\n"); |
| 470 if (FLAG_trace_bailout) PrintF("Non-global scope\n"); | |
| 471 return NORMAL; | 482 return NORMAL; |
| 472 } | 483 } |
| 473 ASSERT(scope->num_heap_slots() == 0); | 484 if (scope->arguments() != NULL) { |
| 474 ASSERT(scope->arguments() == NULL); | 485 if (FLAG_trace_bailout) PrintF("function uses 'arguments'\n"); |
| 486 return NORMAL; |
| 487 } |
| 475 | 488 |
| 476 has_supported_syntax_ = true; | 489 has_supported_syntax_ = true; |
| 477 VisitDeclarations(fun->scope()->declarations()); | 490 VisitDeclarations(scope->declarations()); |
| 478 if (!has_supported_syntax_) return NORMAL; | 491 if (!has_supported_syntax_) return NORMAL; |
| 479 | 492 |
| 480 VisitStatements(fun->body()); | 493 VisitStatements(fun->body()); |
| 481 return has_supported_syntax_ ? FAST : NORMAL; | 494 return has_supported_syntax_ ? FAST : NORMAL; |
| 482 } | 495 } |
| 483 | 496 |
| 484 | 497 |
| 485 #define BAILOUT(reason) \ | 498 #define BAILOUT(reason) \ |
| 486 do { \ | 499 do { \ |
| 487 if (FLAG_trace_bailout) { \ | 500 if (FLAG_trace_bailout) { \ |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 | 977 |
| 965 void CodeGenSelector::VisitThisFunction(ThisFunction* expr) { | 978 void CodeGenSelector::VisitThisFunction(ThisFunction* expr) { |
| 966 BAILOUT("ThisFunction"); | 979 BAILOUT("ThisFunction"); |
| 967 } | 980 } |
| 968 | 981 |
| 969 #undef BAILOUT | 982 #undef BAILOUT |
| 970 #undef CHECK_BAILOUT | 983 #undef CHECK_BAILOUT |
| 971 | 984 |
| 972 | 985 |
| 973 } } // namespace v8::internal | 986 } } // namespace v8::internal |
| OLD | NEW |