| OLD | NEW | 
|    1 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file |    1 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file | 
|    2 // for details. All rights reserved. Use of this source code is governed by a |    2 // for details. All rights reserved. Use of this source code is governed by a | 
|    3 // BSD-style license that can be found in the LICENSE file. |    3 // BSD-style license that can be found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "vm/compiler.h" |    5 #include "vm/compiler.h" | 
|    6  |    6  | 
|    7 #include "vm/assembler.h" |    7 #include "vm/assembler.h" | 
|    8  |    8  | 
|    9 #include "vm/ast_printer.h" |    9 #include "vm/ast_printer.h" | 
|   10 #include "vm/block_scheduler.h" |   10 #include "vm/block_scheduler.h" | 
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   67   const Error& error = Error::Handle(Compiler::CompileFunction(function)); |   67   const Error& error = Error::Handle(Compiler::CompileFunction(function)); | 
|   68   if (!error.IsNull()) { |   68   if (!error.IsNull()) { | 
|   69     Exceptions::PropagateError(error); |   69     Exceptions::PropagateError(error); | 
|   70   } |   70   } | 
|   71 } |   71 } | 
|   72  |   72  | 
|   73  |   73  | 
|   74 RawError* Compiler::Compile(const Library& library, const Script& script) { |   74 RawError* Compiler::Compile(const Library& library, const Script& script) { | 
|   75   Isolate* isolate = Isolate::Current(); |   75   Isolate* isolate = Isolate::Current(); | 
|   76   StackZone zone(isolate); |   76   StackZone zone(isolate); | 
|   77   LongJump* base = isolate->long_jump_base(); |   77   LongJumpScope jump; | 
|   78   LongJump jump; |  | 
|   79   isolate->set_long_jump_base(&jump); |  | 
|   80   if (setjmp(*jump.Set()) == 0) { |   78   if (setjmp(*jump.Set()) == 0) { | 
|   81     if (FLAG_trace_compiler) { |   79     if (FLAG_trace_compiler) { | 
|   82       const String& script_url = String::Handle(script.url()); |   80       const String& script_url = String::Handle(script.url()); | 
|   83       // TODO(iposva): Extract script kind. |   81       // TODO(iposva): Extract script kind. | 
|   84       OS::Print("Compiling %s '%s'\n", "", script_url.ToCString()); |   82       OS::Print("Compiling %s '%s'\n", "", script_url.ToCString()); | 
|   85     } |   83     } | 
|   86     const String& library_key = String::Handle(library.private_key()); |   84     const String& library_key = String::Handle(library.private_key()); | 
|   87     script.Tokenize(library_key); |   85     script.Tokenize(library_key); | 
|   88     Parser::ParseCompilationUnit(library, script); |   86     Parser::ParseCompilationUnit(library, script); | 
|   89     isolate->set_long_jump_base(base); |  | 
|   90     return Error::null(); |   87     return Error::null(); | 
|   91   } else { |   88   } else { | 
|   92     Error& error = Error::Handle(); |   89     Error& error = Error::Handle(); | 
|   93     error = isolate->object_store()->sticky_error(); |   90     error = isolate->object_store()->sticky_error(); | 
|   94     isolate->object_store()->clear_sticky_error(); |   91     isolate->object_store()->clear_sticky_error(); | 
|   95     isolate->set_long_jump_base(base); |  | 
|   96     return error.raw(); |   92     return error.raw(); | 
|   97   } |   93   } | 
|   98   UNREACHABLE(); |   94   UNREACHABLE(); | 
|   99   return Error::null(); |   95   return Error::null(); | 
|  100 } |   96 } | 
|  101  |   97  | 
|  102  |   98  | 
|  103 static void AddRelatedClassesToList(const Class& cls, |   99 static void AddRelatedClassesToList(const Class& cls, | 
|  104                                     const GrowableObjectArray& parse_list, |  100                                     const GrowableObjectArray& parse_list, | 
|  105                                     const GrowableObjectArray& patch_list) { |  101                                     const GrowableObjectArray& patch_list) { | 
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  161   // also allows us to reset the marked_for_parsing state in case we see an |  157   // also allows us to reset the marked_for_parsing state in case we see an | 
|  162   // error. |  158   // error. | 
|  163   Class& parse_class = Class::Handle(); |  159   Class& parse_class = Class::Handle(); | 
|  164   const GrowableObjectArray& parse_list = |  160   const GrowableObjectArray& parse_list = | 
|  165       GrowableObjectArray::Handle(GrowableObjectArray::New(4)); |  161       GrowableObjectArray::Handle(GrowableObjectArray::New(4)); | 
|  166   const GrowableObjectArray& patch_list = |  162   const GrowableObjectArray& patch_list = | 
|  167       GrowableObjectArray::Handle(GrowableObjectArray::New(4)); |  163       GrowableObjectArray::Handle(GrowableObjectArray::New(4)); | 
|  168  |  164  | 
|  169   // Parse the class and all the interfaces it implements and super classes. |  165   // Parse the class and all the interfaces it implements and super classes. | 
|  170   StackZone zone(isolate); |  166   StackZone zone(isolate); | 
|  171   LongJump* base = isolate->long_jump_base(); |  167   LongJumpScope jump; | 
|  172   LongJump jump; |  | 
|  173   isolate->set_long_jump_base(&jump); |  | 
|  174   if (setjmp(*jump.Set()) == 0) { |  168   if (setjmp(*jump.Set()) == 0) { | 
|  175     if (FLAG_trace_compiler) { |  169     if (FLAG_trace_compiler) { | 
|  176       OS::Print("Compiling Class %s '%s'\n", "", cls.ToCString()); |  170       OS::Print("Compiling Class %s '%s'\n", "", cls.ToCString()); | 
|  177     } |  171     } | 
|  178  |  172  | 
|  179     // Add the primary class which needs to be parsed to the parse list. |  173     // Add the primary class which needs to be parsed to the parse list. | 
|  180     // Mark the class as parsed so that we don't recursively add the same |  174     // Mark the class as parsed so that we don't recursively add the same | 
|  181     // class back into the list. |  175     // class back into the list. | 
|  182     parse_list.Add(cls); |  176     parse_list.Add(cls); | 
|  183     cls.set_is_marked_for_parsing(); |  177     cls.set_is_marked_for_parsing(); | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
|  208     } |  202     } | 
|  209  |  203  | 
|  210     // Finalize these classes. |  204     // Finalize these classes. | 
|  211     for (intptr_t i = (parse_list.Length() - 1); i >=0 ; i--) { |  205     for (intptr_t i = (parse_list.Length() - 1); i >=0 ; i--) { | 
|  212       parse_class ^= parse_list.At(i); |  206       parse_class ^= parse_list.At(i); | 
|  213       ASSERT(!parse_class.IsNull()); |  207       ASSERT(!parse_class.IsNull()); | 
|  214       ClassFinalizer::FinalizeClass(parse_class); |  208       ClassFinalizer::FinalizeClass(parse_class); | 
|  215       parse_class.reset_is_marked_for_parsing(); |  209       parse_class.reset_is_marked_for_parsing(); | 
|  216     } |  210     } | 
|  217  |  211  | 
|  218     isolate->set_long_jump_base(base); |  | 
|  219     return Error::null(); |  212     return Error::null(); | 
|  220   } else { |  213   } else { | 
|  221     // Reset the marked for parsing flags. |  214     // Reset the marked for parsing flags. | 
|  222     for (intptr_t i = 0; i < parse_list.Length(); i++) { |  215     for (intptr_t i = 0; i < parse_list.Length(); i++) { | 
|  223       parse_class ^= parse_list.At(i); |  216       parse_class ^= parse_list.At(i); | 
|  224       if (parse_class.is_marked_for_parsing()) { |  217       if (parse_class.is_marked_for_parsing()) { | 
|  225         parse_class.reset_is_marked_for_parsing(); |  218         parse_class.reset_is_marked_for_parsing(); | 
|  226       } |  219       } | 
|  227     } |  220     } | 
|  228     for (intptr_t i = 0; i < patch_list.Length(); i++) { |  221     for (intptr_t i = 0; i < patch_list.Length(); i++) { | 
|  229       parse_class ^= patch_list.At(i); |  222       parse_class ^= patch_list.At(i); | 
|  230       if (parse_class.is_marked_for_parsing()) { |  223       if (parse_class.is_marked_for_parsing()) { | 
|  231         parse_class.reset_is_marked_for_parsing(); |  224         parse_class.reset_is_marked_for_parsing(); | 
|  232       } |  225       } | 
|  233     } |  226     } | 
|  234  |  227  | 
|  235     Error& error = Error::Handle(); |  228     Error& error = Error::Handle(); | 
|  236     error = isolate->object_store()->sticky_error(); |  229     error = isolate->object_store()->sticky_error(); | 
|  237     isolate->object_store()->clear_sticky_error(); |  230     isolate->object_store()->clear_sticky_error(); | 
|  238     isolate->set_long_jump_base(base); |  | 
|  239     return error.raw(); |  231     return error.raw(); | 
|  240   } |  232   } | 
|  241   UNREACHABLE(); |  233   UNREACHABLE(); | 
|  242   return Error::null(); |  234   return Error::null(); | 
|  243 } |  235 } | 
|  244  |  236  | 
|  245  |  237  | 
|  246 static void InstallUnoptimizedCode(const Function& function) { |  238 static void InstallUnoptimizedCode(const Function& function) { | 
|  247   // Disable optimized code. |  239   // Disable optimized code. | 
|  248   ASSERT(function.HasOptimizedCode()); |  240   ASSERT(function.HasOptimizedCode()); | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
|  276   // done is set to false, and use_far_branches is set to true if there is a |  268   // done is set to false, and use_far_branches is set to true if there is a | 
|  277   // longjmp from the ARM or MIPS assemblers. In all other paths through this |  269   // longjmp from the ARM or MIPS assemblers. In all other paths through this | 
|  278   // while loop, done is set to true. use_far_branches is always false on ia32 |  270   // while loop, done is set to true. use_far_branches is always false on ia32 | 
|  279   // and x64. |  271   // and x64. | 
|  280   bool done = false; |  272   bool done = false; | 
|  281   // volatile because the variable may be clobbered by a longjmp. |  273   // volatile because the variable may be clobbered by a longjmp. | 
|  282   volatile bool use_far_branches = false; |  274   volatile bool use_far_branches = false; | 
|  283   while (!done) { |  275   while (!done) { | 
|  284     const intptr_t prev_deopt_id = isolate->deopt_id(); |  276     const intptr_t prev_deopt_id = isolate->deopt_id(); | 
|  285     isolate->set_deopt_id(0); |  277     isolate->set_deopt_id(0); | 
|  286     LongJump* old_base = isolate->long_jump_base(); |  278     LongJumpScope jump; | 
|  287     LongJump bailout_jump; |  279     if (setjmp(*jump.Set()) == 0) { | 
|  288     isolate->set_long_jump_base(&bailout_jump); |  | 
|  289     if (setjmp(*bailout_jump.Set()) == 0) { |  | 
|  290       FlowGraph* flow_graph = NULL; |  280       FlowGraph* flow_graph = NULL; | 
|  291       // TimerScope needs an isolate to be properly terminated in case of a |  281       // TimerScope needs an isolate to be properly terminated in case of a | 
|  292       // LongJump. |  282       // LongJump. | 
|  293       { |  283       { | 
|  294         TimerScope timer(FLAG_compiler_stats, |  284         TimerScope timer(FLAG_compiler_stats, | 
|  295                          &CompilerStats::graphbuilder_timer, |  285                          &CompilerStats::graphbuilder_timer, | 
|  296                          isolate); |  286                          isolate); | 
|  297         Array& ic_data_array = Array::Handle(); |  287         Array& ic_data_array = Array::Handle(); | 
|  298         if (optimized) { |  288         if (optimized) { | 
|  299           ASSERT(function.HasCode()); |  289           ASSERT(function.HasCode()); | 
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  601           OS::Print("%s\n", bailout_error.ToErrorCString()); |  591           OS::Print("%s\n", bailout_error.ToErrorCString()); | 
|  602         } |  592         } | 
|  603         done = true; |  593         done = true; | 
|  604         ASSERT(optimized); |  594         ASSERT(optimized); | 
|  605       } |  595       } | 
|  606  |  596  | 
|  607       isolate->object_store()->clear_sticky_error(); |  597       isolate->object_store()->clear_sticky_error(); | 
|  608       is_compiled = false; |  598       is_compiled = false; | 
|  609     } |  599     } | 
|  610     // Reset global isolate state. |  600     // Reset global isolate state. | 
|  611     isolate->set_long_jump_base(old_base); |  | 
|  612     isolate->set_deopt_id(prev_deopt_id); |  601     isolate->set_deopt_id(prev_deopt_id); | 
|  613   } |  602   } | 
|  614   return is_compiled; |  603   return is_compiled; | 
|  615 } |  604 } | 
|  616  |  605  | 
|  617  |  606  | 
|  618 static void DisassembleCode(const Function& function, bool optimized) { |  607 static void DisassembleCode(const Function& function, bool optimized) { | 
|  619   const char* function_fullname = function.ToFullyQualifiedCString(); |  608   const char* function_fullname = function.ToFullyQualifiedCString(); | 
|  620   OS::Print("Code for %sfunction '%s' {\n", |  609   OS::Print("Code for %sfunction '%s' {\n", | 
|  621             optimized ? "optimized " : "", |  610             optimized ? "optimized " : "", | 
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  738     OS::Print("}\n"); |  727     OS::Print("}\n"); | 
|  739   } |  728   } | 
|  740 } |  729 } | 
|  741  |  730  | 
|  742  |  731  | 
|  743 static RawError* CompileFunctionHelper(const Function& function, |  732 static RawError* CompileFunctionHelper(const Function& function, | 
|  744                                        bool optimized, |  733                                        bool optimized, | 
|  745                                        intptr_t osr_id) { |  734                                        intptr_t osr_id) { | 
|  746   Isolate* isolate = Isolate::Current(); |  735   Isolate* isolate = Isolate::Current(); | 
|  747   StackZone zone(isolate); |  736   StackZone zone(isolate); | 
|  748   LongJump* base = isolate->long_jump_base(); |  737   LongJumpScope jump; | 
|  749   LongJump jump; |  | 
|  750   isolate->set_long_jump_base(&jump); |  | 
|  751   // Make sure unoptimized code is not collected while we are compiling. |  738   // Make sure unoptimized code is not collected while we are compiling. | 
|  752   const Code& unoptimized_code = Code::ZoneHandle(function.unoptimized_code()); |  739   const Code& unoptimized_code = Code::ZoneHandle(function.unoptimized_code()); | 
|  753   // Skips parsing if we need to only install unoptimized code. |  740   // Skips parsing if we need to only install unoptimized code. | 
|  754   if (!optimized && !unoptimized_code.IsNull()) { |  741   if (!optimized && !unoptimized_code.IsNull()) { | 
|  755     InstallUnoptimizedCode(function); |  742     InstallUnoptimizedCode(function); | 
|  756     isolate->set_long_jump_base(base); |  | 
|  757     return Error::null(); |  743     return Error::null(); | 
|  758   } |  744   } | 
|  759   if (setjmp(*jump.Set()) == 0) { |  745   if (setjmp(*jump.Set()) == 0) { | 
|  760     TIMERSCOPE(time_compilation); |  746     TIMERSCOPE(time_compilation); | 
|  761     Timer per_compile_timer(FLAG_trace_compiler, "Compilation time"); |  747     Timer per_compile_timer(FLAG_trace_compiler, "Compilation time"); | 
|  762     per_compile_timer.Start(); |  748     per_compile_timer.Start(); | 
|  763     ParsedFunction* parsed_function = |  749     ParsedFunction* parsed_function = | 
|  764         new ParsedFunction(Function::ZoneHandle(function.raw())); |  750         new ParsedFunction(Function::ZoneHandle(function.raw())); | 
|  765     if (FLAG_trace_compiler) { |  751     if (FLAG_trace_compiler) { | 
|  766       OS::Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", |  752       OS::Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|  780         CompileParsedFunctionHelper(parsed_function, optimized, osr_id); |  766         CompileParsedFunctionHelper(parsed_function, optimized, osr_id); | 
|  781     if (optimized && !success) { |  767     if (optimized && !success) { | 
|  782       // Optimizer bailed out. Disable optimizations and to never try again. |  768       // Optimizer bailed out. Disable optimizations and to never try again. | 
|  783       if (FLAG_trace_compiler) { |  769       if (FLAG_trace_compiler) { | 
|  784         OS::Print("--> disabling optimizations for '%s'\n", |  770         OS::Print("--> disabling optimizations for '%s'\n", | 
|  785                   function.ToFullyQualifiedCString()); |  771                   function.ToFullyQualifiedCString()); | 
|  786       } else if (FLAG_trace_failed_optimization_attempts) { |  772       } else if (FLAG_trace_failed_optimization_attempts) { | 
|  787         OS::Print("Cannot optimize: %s\n", function.ToFullyQualifiedCString()); |  773         OS::Print("Cannot optimize: %s\n", function.ToFullyQualifiedCString()); | 
|  788       } |  774       } | 
|  789       function.SetIsOptimizable(false); |  775       function.SetIsOptimizable(false); | 
|  790       isolate->set_long_jump_base(base); |  | 
|  791       return Error::null(); |  776       return Error::null(); | 
|  792     } |  777     } | 
|  793  |  778  | 
|  794     ASSERT(success); |  779     ASSERT(success); | 
|  795     per_compile_timer.Stop(); |  780     per_compile_timer.Stop(); | 
|  796  |  781  | 
|  797     if (FLAG_trace_compiler) { |  782     if (FLAG_trace_compiler) { | 
|  798       OS::Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n", |  783       OS::Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n", | 
|  799                 function.ToFullyQualifiedCString(), |  784                 function.ToFullyQualifiedCString(), | 
|  800                 Code::Handle(function.CurrentCode()).EntryPoint(), |  785                 Code::Handle(function.CurrentCode()).EntryPoint(), | 
|  801                 Code::Handle(function.CurrentCode()).Size(), |  786                 Code::Handle(function.CurrentCode()).Size(), | 
|  802                 per_compile_timer.TotalElapsedTime()); |  787                 per_compile_timer.TotalElapsedTime()); | 
|  803     } |  788     } | 
|  804  |  789  | 
|  805     isolate->debugger()->NotifyCompilation(function); |  790     isolate->debugger()->NotifyCompilation(function); | 
|  806  |  791  | 
|  807     if (FLAG_disassemble) { |  792     if (FLAG_disassemble) { | 
|  808       DisassembleCode(function, optimized); |  793       DisassembleCode(function, optimized); | 
|  809     } else if (FLAG_disassemble_optimized && optimized) { |  794     } else if (FLAG_disassemble_optimized && optimized) { | 
|  810       // TODO(fschneider): Print unoptimized code along with the optimized code. |  795       // TODO(fschneider): Print unoptimized code along with the optimized code. | 
|  811       OS::Print("*** BEGIN CODE\n"); |  796       OS::Print("*** BEGIN CODE\n"); | 
|  812       DisassembleCode(function, true); |  797       DisassembleCode(function, true); | 
|  813       OS::Print("*** END CODE\n"); |  798       OS::Print("*** END CODE\n"); | 
|  814     } |  799     } | 
|  815  |  800  | 
|  816     isolate->set_long_jump_base(base); |  | 
|  817     return Error::null(); |  801     return Error::null(); | 
|  818   } else { |  802   } else { | 
|  819     Error& error = Error::Handle(); |  803     Error& error = Error::Handle(); | 
|  820     // We got an error during compilation. |  804     // We got an error during compilation. | 
|  821     error = isolate->object_store()->sticky_error(); |  805     error = isolate->object_store()->sticky_error(); | 
|  822     isolate->object_store()->clear_sticky_error(); |  806     isolate->object_store()->clear_sticky_error(); | 
|  823     isolate->set_long_jump_base(base); |  | 
|  824     return error.raw(); |  807     return error.raw(); | 
|  825   } |  808   } | 
|  826   UNREACHABLE(); |  809   UNREACHABLE(); | 
|  827   return Error::null(); |  810   return Error::null(); | 
|  828 } |  811 } | 
|  829  |  812  | 
|  830  |  813  | 
|  831 RawError* Compiler::CompileFunction(const Function& function) { |  814 RawError* Compiler::CompileFunction(const Function& function) { | 
|  832   return CompileFunctionHelper(function, false, Isolate::kNoDeoptId); |  815   return CompileFunctionHelper(function, false, Isolate::kNoDeoptId); | 
|  833 } |  816 } | 
|  834  |  817  | 
|  835  |  818  | 
|  836 RawError* Compiler::CompileOptimizedFunction(const Function& function, |  819 RawError* Compiler::CompileOptimizedFunction(const Function& function, | 
|  837                                              intptr_t osr_id) { |  820                                              intptr_t osr_id) { | 
|  838   return CompileFunctionHelper(function, true, osr_id); |  821   return CompileFunctionHelper(function, true, osr_id); | 
|  839 } |  822 } | 
|  840  |  823  | 
|  841  |  824  | 
|  842 RawError* Compiler::CompileParsedFunction( |  825 RawError* Compiler::CompileParsedFunction( | 
|  843     ParsedFunction* parsed_function) { |  826     ParsedFunction* parsed_function) { | 
|  844   Isolate* isolate = Isolate::Current(); |  827   Isolate* isolate = Isolate::Current(); | 
|  845   LongJump* base = isolate->long_jump_base(); |  828   LongJumpScope jump; | 
|  846   LongJump jump; |  | 
|  847   isolate->set_long_jump_base(&jump); |  | 
|  848   if (setjmp(*jump.Set()) == 0) { |  829   if (setjmp(*jump.Set()) == 0) { | 
|  849     // Non-optimized code generator. |  830     // Non-optimized code generator. | 
|  850     CompileParsedFunctionHelper(parsed_function, false, Isolate::kNoDeoptId); |  831     CompileParsedFunctionHelper(parsed_function, false, Isolate::kNoDeoptId); | 
|  851     if (FLAG_disassemble) { |  832     if (FLAG_disassemble) { | 
|  852       DisassembleCode(parsed_function->function(), false); |  833       DisassembleCode(parsed_function->function(), false); | 
|  853     } |  834     } | 
|  854     isolate->set_long_jump_base(base); |  | 
|  855     return Error::null(); |  835     return Error::null(); | 
|  856   } else { |  836   } else { | 
|  857     Error& error = Error::Handle(); |  837     Error& error = Error::Handle(); | 
|  858     // We got an error during compilation. |  838     // We got an error during compilation. | 
|  859     error = isolate->object_store()->sticky_error(); |  839     error = isolate->object_store()->sticky_error(); | 
|  860     isolate->object_store()->clear_sticky_error(); |  840     isolate->object_store()->clear_sticky_error(); | 
|  861     isolate->set_long_jump_base(base); |  | 
|  862     return error.raw(); |  841     return error.raw(); | 
|  863   } |  842   } | 
|  864   UNREACHABLE(); |  843   UNREACHABLE(); | 
|  865   return Error::null(); |  844   return Error::null(); | 
|  866 } |  845 } | 
|  867  |  846  | 
|  868  |  847  | 
|  869 RawError* Compiler::CompileAllFunctions(const Class& cls) { |  848 RawError* Compiler::CompileAllFunctions(const Class& cls) { | 
|  870   Error& error = Error::Handle(); |  849   Error& error = Error::Handle(); | 
|  871   Array& functions = Array::Handle(cls.functions()); |  850   Array& functions = Array::Handle(cls.functions()); | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  904         } |  883         } | 
|  905       } |  884       } | 
|  906     } |  885     } | 
|  907   } |  886   } | 
|  908   return error.raw(); |  887   return error.raw(); | 
|  909 } |  888 } | 
|  910  |  889  | 
|  911  |  890  | 
|  912 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { |  891 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { | 
|  913   Isolate* isolate = Isolate::Current(); |  892   Isolate* isolate = Isolate::Current(); | 
|  914   LongJump* base = isolate->long_jump_base(); |  893   LongJumpScope jump; | 
|  915   LongJump jump; |  | 
|  916   isolate->set_long_jump_base(&jump); |  | 
|  917   if (setjmp(*jump.Set()) == 0) { |  894   if (setjmp(*jump.Set()) == 0) { | 
|  918     if (FLAG_trace_compiler) { |  895     if (FLAG_trace_compiler) { | 
|  919       OS::Print("compiling expression: "); |  896       OS::Print("compiling expression: "); | 
|  920       AstPrinter::PrintNode(fragment); |  897       AstPrinter::PrintNode(fragment); | 
|  921     } |  898     } | 
|  922  |  899  | 
|  923     // Create a dummy function object for the code generator. |  900     // Create a dummy function object for the code generator. | 
|  924     // The function needs to be associated with a named Class: the interface |  901     // The function needs to be associated with a named Class: the interface | 
|  925     // Function fits the bill. |  902     // Function fits the bill. | 
|  926     const char* kEvalConst = "eval_const"; |  903     const char* kEvalConst = "eval_const"; | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|  949     parsed_function->set_default_parameter_values(Object::null_array()); |  926     parsed_function->set_default_parameter_values(Object::null_array()); | 
|  950     parsed_function->EnsureExpressionTemp(); |  927     parsed_function->EnsureExpressionTemp(); | 
|  951     fragment->scope()->AddVariable(parsed_function->expression_temp_var()); |  928     fragment->scope()->AddVariable(parsed_function->expression_temp_var()); | 
|  952     parsed_function->AllocateVariables(); |  929     parsed_function->AllocateVariables(); | 
|  953  |  930  | 
|  954     // Non-optimized code generator. |  931     // Non-optimized code generator. | 
|  955     CompileParsedFunctionHelper(parsed_function, false, Isolate::kNoDeoptId); |  932     CompileParsedFunctionHelper(parsed_function, false, Isolate::kNoDeoptId); | 
|  956  |  933  | 
|  957     const Object& result = Object::Handle( |  934     const Object& result = Object::Handle( | 
|  958         DartEntry::InvokeFunction(func, Object::empty_array())); |  935         DartEntry::InvokeFunction(func, Object::empty_array())); | 
|  959     isolate->set_long_jump_base(base); |  | 
|  960     return result.raw(); |  936     return result.raw(); | 
|  961   } else { |  937   } else { | 
|  962     const Object& result = |  938     const Object& result = | 
|  963       Object::Handle(isolate->object_store()->sticky_error()); |  939       Object::Handle(isolate->object_store()->sticky_error()); | 
|  964     isolate->object_store()->clear_sticky_error(); |  940     isolate->object_store()->clear_sticky_error(); | 
|  965     isolate->set_long_jump_base(base); |  | 
|  966     return result.raw(); |  941     return result.raw(); | 
|  967   } |  942   } | 
|  968   UNREACHABLE(); |  943   UNREACHABLE(); | 
|  969   return Object::null(); |  944   return Object::null(); | 
|  970 } |  945 } | 
|  971  |  946  | 
|  972 }  // namespace dart |  947 }  // namespace dart | 
| OLD | NEW |