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 |