| OLD | NEW | 
|---|
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 67 | 67 | 
| 68   // Optimize the AST. | 68   // Optimize the AST. | 
| 69   if (!Rewriter::Optimize(literal)) { | 69   if (!Rewriter::Optimize(literal)) { | 
| 70     // Signal a stack overflow by returning a null handle.  The stack | 70     // Signal a stack overflow by returning a null handle.  The stack | 
| 71     // overflow exception will be thrown by the caller. | 71     // overflow exception will be thrown by the caller. | 
| 72     return Handle<Code>::null(); | 72     return Handle<Code>::null(); | 
| 73   } | 73   } | 
| 74 | 74 | 
| 75   // Generate code and return it. | 75   // Generate code and return it. | 
| 76   Handle<Code> result = CodeGenerator::MakeCode(literal, script, is_eval); | 76   Handle<Code> result = CodeGenerator::MakeCode(literal, script, is_eval); | 
|  | 77   // Check for stack-overflow exception. | 
|  | 78   if (result.is_null()) { | 
|  | 79     Top::StackOverflow(); | 
|  | 80     Top::ReportPendingMessages(); | 
|  | 81   } | 
| 77   return result; | 82   return result; | 
| 78 } | 83 } | 
| 79 | 84 | 
| 80 | 85 | 
| 81 static Handle<JSFunction> MakeFunction(bool is_global, | 86 static Handle<JSFunction> MakeFunction(bool is_global, | 
| 82                                        bool is_eval, | 87                                        bool is_eval, | 
| 83                                        Handle<Script> script, | 88                                        Handle<Script> script, | 
| 84                                        v8::Extension* extension, | 89                                        v8::Extension* extension, | 
| 85                                        ScriptDataImpl* pre_data) { | 90                                        ScriptDataImpl* pre_data) { | 
| 86   ZoneScope zone_scope(DELETE_ON_EXIT); | 91   ZoneScope zone_scope(DELETE_ON_EXIT); | 
| 87 | 92 | 
| 88   // Make sure we have an initial stack limit. | 93   // Make sure we have an initial stack limit. | 
| 89   StackGuard guard; | 94   StackGuard guard; | 
| 90   PostponeInterruptsScope postpone; | 95   PostponeInterruptsScope postpone; | 
| 91 | 96 | 
| 92   // Notify debugger | 97   // Notify debugger | 
| 93   Debugger::OnBeforeCompile(script); | 98   Debugger::OnBeforeCompile(script); | 
| 94 | 99 | 
| 95   // Only allow non-global compiles for eval. | 100   // Only allow non-global compiles for eval. | 
| 96   ASSERT(is_eval || is_global); | 101   ASSERT(is_eval || is_global); | 
| 97 | 102 | 
| 98   // Build AST. | 103   // Build AST. | 
| 99   FunctionLiteral* lit = MakeAST(is_global, script, extension, pre_data); | 104   FunctionLiteral* lit = MakeAST(is_global, script, extension, pre_data); | 
| 100 | 105 | 
| 101   // Check for parse errors. | 106   // Check for parse errors. | 
| 102   if (lit == NULL) { | 107   if (lit == NULL) { | 
| 103     ASSERT(Top::has_pending_exception()); | 108     ASSERT(Top::has_pending_exception()); | 
|  | 109     Top::ReportPendingMessages(); | 
| 104     return Handle<JSFunction>::null(); | 110     return Handle<JSFunction>::null(); | 
| 105   } | 111   } | 
| 106 | 112 | 
| 107   // Measure how long it takes to do the compilation; only take the | 113   // Measure how long it takes to do the compilation; only take the | 
| 108   // rest of the function into account to avoid overlap with the | 114   // rest of the function into account to avoid overlap with the | 
| 109   // parsing statistics. | 115   // parsing statistics. | 
| 110   StatsRate* rate = is_eval | 116   StatsRate* rate = is_eval | 
| 111       ? &Counters::compile_eval | 117       ? &Counters::compile_eval | 
| 112       : &Counters::compile; | 118       : &Counters::compile; | 
| 113   StatsRateScope timer(rate); | 119   StatsRateScope timer(rate); | 
| 114 | 120 | 
| 115   // Compile the code. | 121   // Compile the code. | 
| 116   Handle<Code> code = MakeCode(lit, script, is_eval); | 122   Handle<Code> code = MakeCode(lit, script, is_eval); | 
| 117 | 123 | 
| 118   // Check for stack-overflow exceptions. | 124   // Check for stack-overflow exceptions. | 
| 119   if (code.is_null()) { | 125   if (code.is_null()) { | 
| 120     Top::StackOverflow(); |  | 
| 121     return Handle<JSFunction>::null(); | 126     return Handle<JSFunction>::null(); | 
| 122   } | 127   } | 
| 123 | 128 | 
| 124   if (script->name()->IsString()) { | 129   if (script->name()->IsString()) { | 
| 125     SmartPointer<char> data = | 130     SmartPointer<char> data = | 
| 126         String::cast(script->name())->ToCString(DISALLOW_NULLS); | 131         String::cast(script->name())->ToCString(DISALLOW_NULLS); | 
| 127     LOG(CodeCreateEvent(is_eval ? "Eval" : "Script", *code, *data)); | 132     LOG(CodeCreateEvent(is_eval ? "Eval" : "Script", *code, *data)); | 
| 128   } else { | 133   } else { | 
| 129     LOG(CodeCreateEvent(is_eval ? "Eval" : "Script", *code, "")); | 134     LOG(CodeCreateEvent(is_eval ? "Eval" : "Script", *code, "")); | 
| 130   } | 135   } | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 199     if (extension == NULL && !result.is_null()) { | 204     if (extension == NULL && !result.is_null()) { | 
| 200       CompilationCache::PutFunction(source, CompilationCache::SCRIPT, result); | 205       CompilationCache::PutFunction(source, CompilationCache::SCRIPT, result); | 
| 201     } | 206     } | 
| 202 | 207 | 
| 203     // Get rid of the pre-parsing data (if necessary). | 208     // Get rid of the pre-parsing data (if necessary). | 
| 204     if (input_pre_data == NULL && pre_data != NULL) { | 209     if (input_pre_data == NULL && pre_data != NULL) { | 
| 205       delete pre_data; | 210       delete pre_data; | 
| 206     } | 211     } | 
| 207   } | 212   } | 
| 208 | 213 | 
|  | 214   if (result.is_null()) Top::ReportPendingMessages(); | 
|  | 215 | 
| 209   return result; | 216   return result; | 
| 210 } | 217 } | 
| 211 | 218 | 
| 212 | 219 | 
| 213 Handle<JSFunction> Compiler::CompileEval(Handle<String> source, | 220 Handle<JSFunction> Compiler::CompileEval(Handle<String> source, | 
| 214                                          int line_offset, | 221                                          int line_offset, | 
| 215                                          bool is_global) { | 222                                          bool is_global) { | 
| 216   int source_length = source->length(); | 223   int source_length = source->length(); | 
| 217   Counters::total_eval_size.Increment(source_length); | 224   Counters::total_eval_size.Increment(source_length); | 
| 218   Counters::total_compile_size.Increment(source_length); | 225   Counters::total_compile_size.Increment(source_length); | 
| 219 | 226 | 
| 220   // The VM is in the COMPILER state until exiting this function. | 227   // The VM is in the COMPILER state until exiting this function. | 
| 221   VMState state(COMPILER); | 228   VMState state(COMPILER); | 
| 222   CompilationCache::Entry entry = is_global | 229   CompilationCache::Entry entry = is_global | 
| 223       ? CompilationCache::EVAL_GLOBAL | 230       ? CompilationCache::EVAL_GLOBAL | 
| 224       : CompilationCache::EVAL_CONTEXTUAL; | 231       : CompilationCache::EVAL_CONTEXTUAL; | 
| 225 | 232 | 
| 226   // Do a lookup in the compilation cache; if the entry is not there, | 233   // Do a lookup in the compilation cache; if the entry is not there, | 
| 227   // invoke the compiler and add the result to the cache. | 234   // invoke the compiler and add the result to the cache. | 
| 228   Handle<JSFunction> result = CompilationCache::LookupEval(source, entry); | 235   Handle<JSFunction> result = CompilationCache::LookupEval(source, entry); | 
| 229   if (result.is_null()) { | 236   if (result.is_null()) { | 
| 230     // Create a script object describing the script to be compiled. | 237     // Create a script object describing the script to be compiled. | 
| 231     Handle<Script> script = Factory::NewScript(source); | 238     Handle<Script> script = Factory::NewScript(source); | 
| 232     script->set_line_offset(Smi::FromInt(line_offset)); | 239     script->set_line_offset(Smi::FromInt(line_offset)); | 
| 233     result = MakeFunction(is_global, true, script, NULL, NULL); | 240     result = MakeFunction(is_global, true, script, NULL, NULL); | 
| 234     if (!result.is_null()) { | 241     if (!result.is_null()) { | 
| 235       CompilationCache::PutFunction(source, entry, result); | 242       CompilationCache::PutFunction(source, entry, result); | 
| 236     } | 243     } | 
| 237   } | 244   } | 
|  | 245 | 
|  | 246   if (result.is_null()) Top::ReportPendingMessages(); | 
|  | 247 | 
| 238   return result; | 248   return result; | 
| 239 } | 249 } | 
| 240 | 250 | 
| 241 | 251 | 
| 242 bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared, | 252 bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared, | 
| 243                            int loop_nesting) { | 253                            int loop_nesting) { | 
| 244   ZoneScope zone_scope(DELETE_ON_EXIT); | 254   ZoneScope zone_scope(DELETE_ON_EXIT); | 
| 245 | 255 | 
| 246   // The VM is in the COMPILER state until exiting this function. | 256   // The VM is in the COMPILER state until exiting this function. | 
| 247   VMState state(COMPILER); | 257   VMState state(COMPILER); | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 262   // Generate the AST for the lazily compiled function. The AST may be | 272   // Generate the AST for the lazily compiled function. The AST may be | 
| 263   // NULL in case of parser stack overflow. | 273   // NULL in case of parser stack overflow. | 
| 264   FunctionLiteral* lit = MakeLazyAST(script, name, | 274   FunctionLiteral* lit = MakeLazyAST(script, name, | 
| 265                                      start_position, | 275                                      start_position, | 
| 266                                      end_position, | 276                                      end_position, | 
| 267                                      is_expression); | 277                                      is_expression); | 
| 268 | 278 | 
| 269   // Check for parse errors. | 279   // Check for parse errors. | 
| 270   if (lit == NULL) { | 280   if (lit == NULL) { | 
| 271     ASSERT(Top::has_pending_exception()); | 281     ASSERT(Top::has_pending_exception()); | 
|  | 282     Top::ReportPendingMessages(); | 
| 272     return false; | 283     return false; | 
| 273   } | 284   } | 
| 274 | 285 | 
| 275   // Update the loop nesting in the function literal. | 286   // Update the loop nesting in the function literal. | 
| 276   lit->set_loop_nesting(loop_nesting); | 287   lit->set_loop_nesting(loop_nesting); | 
| 277 | 288 | 
| 278   // Measure how long it takes to do the lazy compilation; only take | 289   // Measure how long it takes to do the lazy compilation; only take | 
| 279   // the rest of the function into account to avoid overlap with the | 290   // the rest of the function into account to avoid overlap with the | 
| 280   // lazy parsing statistics. | 291   // lazy parsing statistics. | 
| 281   StatsRateScope timer(&Counters::compile_lazy); | 292   StatsRateScope timer(&Counters::compile_lazy); | 
| 282 | 293 | 
| 283   // Compile the code. | 294   // Compile the code. | 
| 284   Handle<Code> code = MakeCode(lit, script, false); | 295   Handle<Code> code = MakeCode(lit, script, false); | 
| 285 | 296 | 
| 286   // Check for stack-overflow exception. |  | 
| 287   if (code.is_null()) { | 297   if (code.is_null()) { | 
| 288     Top::StackOverflow(); |  | 
| 289     return false; | 298     return false; | 
| 290   } | 299   } | 
| 291 | 300 | 
| 292   // Generate the code, update the function info, and return the code. | 301   // Generate the code, update the function info, and return the code. | 
| 293   LOG(CodeCreateEvent("LazyCompile", *code, *lit->name())); | 302   LOG(CodeCreateEvent("LazyCompile", *code, *lit->name())); | 
| 294 | 303 | 
| 295   // Update the shared function info with the compiled code. | 304   // Update the shared function info with the compiled code. | 
| 296   shared->set_code(*code); | 305   shared->set_code(*code); | 
| 297 | 306 | 
| 298   // Set the expected number of properties for instances. | 307   // Set the expected number of properties for instances. | 
| 299   SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); | 308   SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); | 
| 300 | 309 | 
| 301   // Check the function has compiled code. | 310   // Check the function has compiled code. | 
| 302   ASSERT(shared->is_compiled()); | 311   ASSERT(shared->is_compiled()); | 
| 303   return true; | 312   return true; | 
| 304 } | 313 } | 
| 305 | 314 | 
| 306 | 315 | 
| 307 } }  // namespace v8::internal | 316 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|