| 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 | 
|---|