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 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 Parser::ParseCompilationUnit(library, script); | 101 Parser::ParseCompilationUnit(library, script); |
102 } else { | 102 } else { |
103 error = isolate->object_store()->sticky_error(); | 103 error = isolate->object_store()->sticky_error(); |
104 isolate->object_store()->clear_sticky_error(); | 104 isolate->object_store()->clear_sticky_error(); |
105 } | 105 } |
106 isolate->set_long_jump_base(base); | 106 isolate->set_long_jump_base(base); |
107 return error.raw(); | 107 return error.raw(); |
108 } | 108 } |
109 | 109 |
110 | 110 |
| 111 static void InstallUnoptimizedCode(const Function& function) { |
| 112 // Disable optimized code. |
| 113 ASSERT(function.HasOptimizedCode()); |
| 114 // Patch entry of optimized code. |
| 115 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); |
| 116 if (FLAG_trace_compiler) { |
| 117 OS::Print("--> patching entry 0x%x\n", |
| 118 Code::Handle(function.CurrentCode()).EntryPoint()); |
| 119 } |
| 120 // Use previously compiled code. |
| 121 function.SetCode(Code::Handle(function.unoptimized_code())); |
| 122 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code())); |
| 123 if (FLAG_trace_compiler) { |
| 124 OS::Print("--> restoring entry at 0x%x\n", |
| 125 Code::Handle(function.unoptimized_code()).EntryPoint()); |
| 126 } |
| 127 } |
| 128 |
| 129 |
111 static RawError* CompileFunctionHelper(const Function& function, | 130 static RawError* CompileFunctionHelper(const Function& function, |
112 bool optimized) { | 131 bool optimized) { |
113 Isolate* isolate = Isolate::Current(); | 132 Isolate* isolate = Isolate::Current(); |
114 Error& error = Error::Handle(); | 133 Error& error = Error::Handle(); |
115 LongJump* base = isolate->long_jump_base(); | 134 LongJump* base = isolate->long_jump_base(); |
116 LongJump jump; | 135 LongJump jump; |
117 isolate->set_long_jump_base(&jump); | 136 isolate->set_long_jump_base(&jump); |
| 137 // Skips parsing if we need to only install unoptimized code. |
| 138 if (!optimized && !Code::Handle(function.unoptimized_code()).IsNull()) { |
| 139 InstallUnoptimizedCode(function); |
| 140 return Error::null(); |
| 141 } |
118 if (setjmp(*jump.Set()) == 0) { | 142 if (setjmp(*jump.Set()) == 0) { |
119 TIMERSCOPE(time_compilation); | 143 TIMERSCOPE(time_compilation); |
120 ParsedFunction parsed_function(function); | 144 ParsedFunction parsed_function(function); |
121 const char* function_fullname = function.ToFullyQualifiedCString(); | 145 const char* function_fullname = function.ToFullyQualifiedCString(); |
122 if (FLAG_trace_compiler) { | 146 if (FLAG_trace_compiler) { |
123 OS::Print("Compiling %sfunction: '%s' @ token %d\n", | 147 OS::Print("Compiling %sfunction: '%s' @ token %d\n", |
124 (optimized ? "optimized " : ""), | 148 (optimized ? "optimized " : ""), |
125 function_fullname, | 149 function_fullname, |
126 function.token_index()); | 150 function.token_index()); |
127 } | 151 } |
128 Parser::ParseFunction(&parsed_function); | 152 Parser::ParseFunction(&parsed_function); |
129 parsed_function.AllocateVariables(); | 153 parsed_function.AllocateVariables(); |
130 | 154 |
131 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); | 155 TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer); |
132 | |
133 bool is_compiled = false; | 156 bool is_compiled = false; |
134 if (FLAG_use_new_compiler) { | 157 if (FLAG_use_new_compiler) { |
135 ASSERT(!optimized); | 158 ASSERT(!optimized); |
136 LongJump* old_base = isolate->long_jump_base(); | 159 LongJump* old_base = isolate->long_jump_base(); |
137 LongJump bailout_jump; | 160 LongJump bailout_jump; |
138 isolate->set_long_jump_base(&bailout_jump); | 161 isolate->set_long_jump_base(&bailout_jump); |
139 if (setjmp(*bailout_jump.Set()) == 0) { | 162 if (setjmp(*bailout_jump.Set()) == 0) { |
140 FlowGraphBuilder graph_builder(parsed_function); | 163 FlowGraphBuilder graph_builder(parsed_function); |
141 graph_builder.BuildGraph(); | 164 graph_builder.BuildGraph(); |
142 | 165 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 code_gen.FinalizePcDescriptors(code); | 220 code_gen.FinalizePcDescriptors(code); |
198 code_gen.FinalizeStackmaps(code); | 221 code_gen.FinalizeStackmaps(code); |
199 code_gen.FinalizeExceptionHandlers(code); | 222 code_gen.FinalizeExceptionHandlers(code); |
200 function.SetCode(code); | 223 function.SetCode(code); |
201 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code())); | 224 CodePatcher::PatchEntry(Code::Handle(function.unoptimized_code())); |
202 if (FLAG_trace_compiler) { | 225 if (FLAG_trace_compiler) { |
203 OS::Print("--> patching entry 0x%x\n", | 226 OS::Print("--> patching entry 0x%x\n", |
204 Code::Handle(function.unoptimized_code()).EntryPoint()); | 227 Code::Handle(function.unoptimized_code()).EntryPoint()); |
205 } | 228 } |
206 } else { | 229 } else { |
207 // Unoptimized code. | 230 // Compile unnoptimized code. |
208 if (Code::Handle(function.unoptimized_code()).IsNull()) { | 231 ASSERT(!function.HasCode()); |
209 ASSERT(!function.HasCode()); | 232 // Compiling first time. |
210 // Compiling first time. | 233 CodeGenerator code_gen(&assembler, parsed_function); |
211 CodeGenerator code_gen(&assembler, parsed_function); | 234 code_gen.GenerateCode(); |
212 code_gen.GenerateCode(); | 235 const Code& code = |
213 const Code& code = | 236 Code::Handle(Code::FinalizeCode(function_fullname, &assembler)); |
214 Code::Handle(Code::FinalizeCode(function_fullname, &assembler)); | 237 code.set_is_optimized(false); |
215 code.set_is_optimized(false); | 238 code_gen.FinalizePcDescriptors(code); |
216 code_gen.FinalizePcDescriptors(code); | 239 code_gen.FinalizeStackmaps(code); |
217 code_gen.FinalizeStackmaps(code); | 240 code_gen.FinalizeVarDescriptors(code); |
218 code_gen.FinalizeVarDescriptors(code); | 241 code_gen.FinalizeExceptionHandlers(code); |
219 code_gen.FinalizeExceptionHandlers(code); | 242 function.set_unoptimized_code(code); |
220 function.set_unoptimized_code(code); | 243 function.SetCode(code); |
221 function.SetCode(code); | 244 ASSERT(CodePatcher::CodeIsPatchable(code)); |
222 ASSERT(CodePatcher::CodeIsPatchable(code)); | |
223 } else { | |
224 // Disable optimized code. | |
225 ASSERT(function.HasOptimizedCode()); | |
226 // Patch entry of optimized code. | |
227 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); | |
228 if (FLAG_trace_compiler) { | |
229 OS::Print("--> patching entry 0x%x\n", | |
230 Code::Handle(function.CurrentCode()).EntryPoint()); | |
231 } | |
232 // Use previously compiled code. | |
233 function.SetCode(Code::Handle(function.unoptimized_code())); | |
234 CodePatcher::RestoreEntry(Code::Handle(function.unoptimized_code())); | |
235 if (FLAG_trace_compiler) { | |
236 OS::Print("--> restoring entry at 0x%x\n", | |
237 Code::Handle(function.unoptimized_code()).EntryPoint()); | |
238 } | |
239 } | |
240 } | 245 } |
241 } | 246 } |
242 if (FLAG_trace_compiler) { | 247 if (FLAG_trace_compiler) { |
243 OS::Print("--> '%s' entry: 0x%x\n", | 248 OS::Print("--> '%s' entry: 0x%x\n", |
244 function_fullname, | 249 function_fullname, |
245 Code::Handle(function.CurrentCode()).EntryPoint()); | 250 Code::Handle(function.CurrentCode()).EntryPoint()); |
246 } | 251 } |
247 if (Isolate::Current()->debugger()->IsActive()) { | 252 if (Isolate::Current()->debugger()->IsActive()) { |
248 Isolate::Current()->debugger()->NotifyCompilation(function); | 253 Isolate::Current()->debugger()->NotifyCompilation(function); |
249 } | 254 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 // We got an error during compilation. | 302 // We got an error during compilation. |
298 error = isolate->object_store()->sticky_error(); | 303 error = isolate->object_store()->sticky_error(); |
299 isolate->object_store()->clear_sticky_error(); | 304 isolate->object_store()->clear_sticky_error(); |
300 } | 305 } |
301 isolate->set_long_jump_base(base); | 306 isolate->set_long_jump_base(base); |
302 return error.raw(); | 307 return error.raw(); |
303 } | 308 } |
304 | 309 |
305 | 310 |
306 RawError* Compiler::CompileFunction(const Function& function) { | 311 RawError* Compiler::CompileFunction(const Function& function) { |
307 return CompileFunctionHelper(function, false); | 312 return CompileFunctionHelper(function, false); // Non-optimized. |
308 } | 313 } |
309 | 314 |
310 | 315 |
311 RawError* Compiler::CompileOptimizedFunction(const Function& function) { | 316 RawError* Compiler::CompileOptimizedFunction(const Function& function) { |
312 return CompileFunctionHelper(function, true); | 317 return CompileFunctionHelper(function, true); // Optimized. |
313 } | 318 } |
314 | 319 |
315 | 320 |
316 RawError* Compiler::CompileAllFunctions(const Class& cls) { | 321 RawError* Compiler::CompileAllFunctions(const Class& cls) { |
317 Error& error = Error::Handle(); | 322 Error& error = Error::Handle(); |
318 Array& functions = Array::Handle(cls.functions()); | 323 Array& functions = Array::Handle(cls.functions()); |
319 Function& func = Function::Handle(); | 324 Function& func = Function::Handle(); |
320 for (int i = 0; i < functions.Length(); i++) { | 325 for (int i = 0; i < functions.Length(); i++) { |
321 func ^= functions.At(i); | 326 func ^= functions.At(i); |
322 ASSERT(!func.IsNull()); | 327 ASSERT(!func.IsNull()); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 } else { | 391 } else { |
387 result = isolate->object_store()->sticky_error(); | 392 result = isolate->object_store()->sticky_error(); |
388 isolate->object_store()->clear_sticky_error(); | 393 isolate->object_store()->clear_sticky_error(); |
389 } | 394 } |
390 isolate->set_long_jump_base(base); | 395 isolate->set_long_jump_base(base); |
391 return result.raw(); | 396 return result.raw(); |
392 } | 397 } |
393 | 398 |
394 | 399 |
395 } // namespace dart | 400 } // namespace dart |
OLD | NEW |