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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 Error::Handle(Compiler::CompileFunction(thread, function)); | 180 Error::Handle(Compiler::CompileFunction(thread, function)); |
181 if (!error.IsNull()) { | 181 if (!error.IsNull()) { |
182 Exceptions::PropagateError(error); | 182 Exceptions::PropagateError(error); |
183 } | 183 } |
184 } | 184 } |
185 | 185 |
186 | 186 |
187 RawError* Compiler::Compile(const Library& library, const Script& script) { | 187 RawError* Compiler::Compile(const Library& library, const Script& script) { |
188 LongJumpScope jump; | 188 LongJumpScope jump; |
189 if (setjmp(*jump.Set()) == 0) { | 189 if (setjmp(*jump.Set()) == 0) { |
190 Isolate* const isolate = Isolate::Current(); | 190 Thread* const thread = Thread::Current(); |
191 StackZone zone(isolate); | 191 StackZone zone(thread); |
192 if (FLAG_trace_compiler) { | 192 if (FLAG_trace_compiler) { |
193 const String& script_url = String::Handle(script.url()); | 193 const String& script_url = String::Handle(script.url()); |
194 // TODO(iposva): Extract script kind. | 194 // TODO(iposva): Extract script kind. |
195 ISL_Print("Compiling %s '%s'\n", "", script_url.ToCString()); | 195 ISL_Print("Compiling %s '%s'\n", "", script_url.ToCString()); |
196 } | 196 } |
197 const String& library_key = String::Handle(library.private_key()); | 197 const String& library_key = String::Handle(library.private_key()); |
198 script.Tokenize(library_key); | 198 script.Tokenize(library_key); |
199 Parser::ParseCompilationUnit(library, script); | 199 Parser::ParseCompilationUnit(library, script); |
200 return Error::null(); | 200 return Error::null(); |
201 } else { | 201 } else { |
202 Isolate* const isolate = Isolate::Current(); | 202 Thread* const thread = Thread::Current(); |
203 StackZone zone(isolate); | 203 Isolate* const isolate = thread->isolate(); |
| 204 StackZone zone(thread); |
204 Error& error = Error::Handle(); | 205 Error& error = Error::Handle(); |
205 error = isolate->object_store()->sticky_error(); | 206 error = isolate->object_store()->sticky_error(); |
206 isolate->object_store()->clear_sticky_error(); | 207 isolate->object_store()->clear_sticky_error(); |
207 return error.raw(); | 208 return error.raw(); |
208 } | 209 } |
209 UNREACHABLE(); | 210 UNREACHABLE(); |
210 return Error::null(); | 211 return Error::null(); |
211 } | 212 } |
212 | 213 |
213 | 214 |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 intptr_t osr_id) { | 389 intptr_t osr_id) { |
389 const Function& function = parsed_function->function(); | 390 const Function& function = parsed_function->function(); |
390 if (optimized && !function.IsOptimizable()) { | 391 if (optimized && !function.IsOptimizable()) { |
391 return false; | 392 return false; |
392 } | 393 } |
393 bool is_compiled = false; | 394 bool is_compiled = false; |
394 Thread* const thread = Thread::Current(); | 395 Thread* const thread = Thread::Current(); |
395 Zone* const zone = thread->zone(); | 396 Zone* const zone = thread->zone(); |
396 Isolate* const isolate = thread->isolate(); | 397 Isolate* const isolate = thread->isolate(); |
397 CSTAT_TIMER_SCOPE(isolate, codegen_timer); | 398 CSTAT_TIMER_SCOPE(isolate, codegen_timer); |
398 HANDLESCOPE(isolate); | 399 HANDLESCOPE(thread); |
399 | 400 |
400 // We may reattempt compilation if the function needs to be assembled using | 401 // We may reattempt compilation if the function needs to be assembled using |
401 // far branches on ARM and MIPS. In the else branch of the setjmp call, | 402 // far branches on ARM and MIPS. In the else branch of the setjmp call, |
402 // done is set to false, and use_far_branches is set to true if there is a | 403 // done is set to false, and use_far_branches is set to true if there is a |
403 // longjmp from the ARM or MIPS assemblers. In all other paths through this | 404 // longjmp from the ARM or MIPS assemblers. In all other paths through this |
404 // while loop, done is set to true. use_far_branches is always false on ia32 | 405 // while loop, done is set to true. use_far_branches is always false on ia32 |
405 // and x64. | 406 // and x64. |
406 bool done = false; | 407 bool done = false; |
407 // volatile because the variable may be clobbered by a longjmp. | 408 // volatile because the variable may be clobbered by a longjmp. |
408 volatile bool use_far_branches = false; | 409 volatile bool use_far_branches = false; |
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1006 intptr_t osr_id) { | 1007 intptr_t osr_id) { |
1007 // Check that we optimize if 'Compiler::always_optimize()' is set to true, | 1008 // Check that we optimize if 'Compiler::always_optimize()' is set to true, |
1008 // except if the function is marked as not optimizable. | 1009 // except if the function is marked as not optimizable. |
1009 ASSERT(!function.IsOptimizable() || | 1010 ASSERT(!function.IsOptimizable() || |
1010 !Compiler::always_optimize() || optimized); | 1011 !Compiler::always_optimize() || optimized); |
1011 ASSERT(Compiler::allow_recompilation() || !function.HasCode()); | 1012 ASSERT(Compiler::allow_recompilation() || !function.HasCode()); |
1012 LongJumpScope jump; | 1013 LongJumpScope jump; |
1013 if (setjmp(*jump.Set()) == 0) { | 1014 if (setjmp(*jump.Set()) == 0) { |
1014 Thread* const thread = Thread::Current(); | 1015 Thread* const thread = Thread::Current(); |
1015 Isolate* const isolate = thread->isolate(); | 1016 Isolate* const isolate = thread->isolate(); |
1016 StackZone stack_zone(isolate); | 1017 StackZone stack_zone(thread); |
1017 Zone* const zone = stack_zone.GetZone(); | 1018 Zone* const zone = stack_zone.GetZone(); |
1018 TIMERSCOPE(isolate, time_compilation); | 1019 TIMERSCOPE(isolate, time_compilation); |
1019 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time"); | 1020 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time"); |
1020 per_compile_timer.Start(); | 1021 per_compile_timer.Start(); |
1021 | 1022 |
1022 // Restore unoptimized code if needed. | 1023 // Restore unoptimized code if needed. |
1023 if (optimized) { | 1024 if (optimized) { |
1024 if (!Compiler::always_optimize()) { | 1025 if (!Compiler::always_optimize()) { |
1025 const Error& error = Error::Handle( | 1026 const Error& error = Error::Handle( |
1026 zone, Compiler::EnsureUnoptimizedCode(Thread::Current(), function)); | 1027 zone, Compiler::EnsureUnoptimizedCode(Thread::Current(), function)); |
1027 if (!error.IsNull()) { | 1028 if (!error.IsNull()) { |
1028 return error.raw(); | 1029 return error.raw(); |
1029 } | 1030 } |
1030 } | 1031 } |
1031 } | 1032 } |
1032 | 1033 |
1033 ParsedFunction* parsed_function = new(zone) ParsedFunction( | 1034 ParsedFunction* parsed_function = new(zone) ParsedFunction( |
1034 thread, Function::ZoneHandle(zone, function.raw())); | 1035 thread, Function::ZoneHandle(zone, function.raw())); |
1035 if (FLAG_trace_compiler) { | 1036 if (FLAG_trace_compiler) { |
1036 ISL_Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", | 1037 ISL_Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", |
1037 (osr_id == Isolate::kNoDeoptId ? "" : "osr "), | 1038 (osr_id == Isolate::kNoDeoptId ? "" : "osr "), |
1038 (optimized ? "optimized " : ""), | 1039 (optimized ? "optimized " : ""), |
1039 function.ToFullyQualifiedCString(), | 1040 function.ToFullyQualifiedCString(), |
1040 function.token_pos(), | 1041 function.token_pos(), |
1041 (function.end_token_pos() - function.token_pos())); | 1042 (function.end_token_pos() - function.token_pos())); |
1042 } | 1043 } |
1043 { | 1044 { |
1044 HANDLESCOPE(isolate); | 1045 HANDLESCOPE(thread); |
1045 pipeline->ParseFunction(parsed_function); | 1046 pipeline->ParseFunction(parsed_function); |
1046 } | 1047 } |
1047 | 1048 |
1048 const bool success = CompileParsedFunctionHelper(pipeline, | 1049 const bool success = CompileParsedFunctionHelper(pipeline, |
1049 parsed_function, | 1050 parsed_function, |
1050 optimized, | 1051 optimized, |
1051 osr_id); | 1052 osr_id); |
1052 if (!success) { | 1053 if (!success) { |
1053 if (optimized) { | 1054 if (optimized) { |
1054 ASSERT(!Compiler::always_optimize()); // Optimized is the only code. | 1055 ASSERT(!Compiler::always_optimize()); // Optimized is the only code. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1088 DisassembleCode(function, true); | 1089 DisassembleCode(function, true); |
1089 ISL_Print("*** END CODE\n"); | 1090 ISL_Print("*** END CODE\n"); |
1090 } | 1091 } |
1091 #if defined(DEBUG) | 1092 #if defined(DEBUG) |
1092 CheckInliningIntervals(function); | 1093 CheckInliningIntervals(function); |
1093 #endif | 1094 #endif |
1094 return Error::null(); | 1095 return Error::null(); |
1095 } else { | 1096 } else { |
1096 Thread* const thread = Thread::Current(); | 1097 Thread* const thread = Thread::Current(); |
1097 Isolate* const isolate = thread->isolate(); | 1098 Isolate* const isolate = thread->isolate(); |
1098 StackZone stack_zone(isolate); | 1099 StackZone stack_zone(thread); |
1099 Error& error = Error::Handle(); | 1100 Error& error = Error::Handle(); |
1100 // We got an error during compilation. | 1101 // We got an error during compilation. |
1101 error = isolate->object_store()->sticky_error(); | 1102 error = isolate->object_store()->sticky_error(); |
1102 isolate->object_store()->clear_sticky_error(); | 1103 isolate->object_store()->clear_sticky_error(); |
1103 return error.raw(); | 1104 return error.raw(); |
1104 } | 1105 } |
1105 UNREACHABLE(); | 1106 UNREACHABLE(); |
1106 return Error::null(); | 1107 return Error::null(); |
1107 } | 1108 } |
1108 | 1109 |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1282 | 1283 |
1283 void Compiler::CompileStaticInitializer(const Field& field) { | 1284 void Compiler::CompileStaticInitializer(const Field& field) { |
1284 ASSERT(field.is_static()); | 1285 ASSERT(field.is_static()); |
1285 if (field.initializer() != Function::null()) { | 1286 if (field.initializer() != Function::null()) { |
1286 // TODO(rmacnak): Investigate why this happens for _enum_names. | 1287 // TODO(rmacnak): Investigate why this happens for _enum_names. |
1287 OS::Print("Warning: Ignoring repeated request for initializer for %s\n", | 1288 OS::Print("Warning: Ignoring repeated request for initializer for %s\n", |
1288 field.ToCString()); | 1289 field.ToCString()); |
1289 return; | 1290 return; |
1290 } | 1291 } |
1291 ASSERT(field.initializer() == Function::null()); | 1292 ASSERT(field.initializer() == Function::null()); |
1292 Isolate* isolate = Isolate::Current(); | 1293 Thread* thread = Thread::Current(); |
1293 StackZone zone(isolate); | 1294 StackZone zone(thread); |
1294 | 1295 |
1295 ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field); | 1296 ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field); |
1296 | 1297 |
1297 parsed_function->AllocateVariables(); | 1298 parsed_function->AllocateVariables(); |
1298 // Non-optimized code generator. | 1299 // Non-optimized code generator. |
1299 DartCompilationPipeline pipeline; | 1300 DartCompilationPipeline pipeline; |
1300 CompileParsedFunctionHelper(&pipeline, | 1301 CompileParsedFunctionHelper(&pipeline, |
1301 parsed_function, | 1302 parsed_function, |
1302 false, // optimized | 1303 false, // optimized |
1303 Isolate::kNoDeoptId); | 1304 Isolate::kNoDeoptId); |
(...skipping 10 matching lines...) Expand all Loading... |
1314 ASSERT(field.value() == Object::transition_sentinel().raw()); | 1315 ASSERT(field.value() == Object::transition_sentinel().raw()); |
1315 LongJumpScope jump; | 1316 LongJumpScope jump; |
1316 if (setjmp(*jump.Set()) == 0) { | 1317 if (setjmp(*jump.Set()) == 0) { |
1317 Function& initializer = Function::Handle(field.initializer()); | 1318 Function& initializer = Function::Handle(field.initializer()); |
1318 | 1319 |
1319 // Under precompilation, the initializer may have already been compiled, in | 1320 // Under precompilation, the initializer may have already been compiled, in |
1320 // which case use it. Under lazy compilation or early in precompilation, the | 1321 // which case use it. Under lazy compilation or early in precompilation, the |
1321 // initializer has not yet been created, so create it now, but don't bother | 1322 // initializer has not yet been created, so create it now, but don't bother |
1322 // remembering it because it won't be used again. | 1323 // remembering it because it won't be used again. |
1323 if (initializer.IsNull()) { | 1324 if (initializer.IsNull()) { |
1324 Isolate* const isolate = Isolate::Current(); | 1325 Thread* const thread = Thread::Current(); |
1325 StackZone zone(isolate); | 1326 StackZone zone(thread); |
1326 ParsedFunction* parsed_function = | 1327 ParsedFunction* parsed_function = |
1327 Parser::ParseStaticFieldInitializer(field); | 1328 Parser::ParseStaticFieldInitializer(field); |
1328 | 1329 |
1329 parsed_function->AllocateVariables(); | 1330 parsed_function->AllocateVariables(); |
1330 // Non-optimized code generator. | 1331 // Non-optimized code generator. |
1331 DartCompilationPipeline pipeline; | 1332 DartCompilationPipeline pipeline; |
1332 CompileParsedFunctionHelper(&pipeline, | 1333 CompileParsedFunctionHelper(&pipeline, |
1333 parsed_function, | 1334 parsed_function, |
1334 false, // optimized | 1335 false, // optimized |
1335 Isolate::kNoDeoptId); | 1336 Isolate::kNoDeoptId); |
1336 // Eagerly create local var descriptors. | 1337 // Eagerly create local var descriptors. |
1337 CreateLocalVarDescriptors(*parsed_function); | 1338 CreateLocalVarDescriptors(*parsed_function); |
1338 | 1339 |
1339 initializer = parsed_function->function().raw(); | 1340 initializer = parsed_function->function().raw(); |
1340 } | 1341 } |
1341 // Invoke the function to evaluate the expression. | 1342 // Invoke the function to evaluate the expression. |
1342 const Object& result = PassiveObject::Handle( | 1343 const Object& result = PassiveObject::Handle( |
1343 DartEntry::InvokeFunction(initializer, Object::empty_array())); | 1344 DartEntry::InvokeFunction(initializer, Object::empty_array())); |
1344 return result.raw(); | 1345 return result.raw(); |
1345 } else { | 1346 } else { |
1346 Isolate* const isolate = Isolate::Current(); | 1347 Thread* const thread = Thread::Current(); |
1347 StackZone zone(isolate); | 1348 Isolate* const isolate = thread->isolate(); |
| 1349 StackZone zone(thread); |
1348 const Error& error = | 1350 const Error& error = |
1349 Error::Handle(isolate, isolate->object_store()->sticky_error()); | 1351 Error::Handle(isolate, isolate->object_store()->sticky_error()); |
1350 isolate->object_store()->clear_sticky_error(); | 1352 isolate->object_store()->clear_sticky_error(); |
1351 return error.raw(); | 1353 return error.raw(); |
1352 } | 1354 } |
1353 UNREACHABLE(); | 1355 UNREACHABLE(); |
1354 return Object::null(); | 1356 return Object::null(); |
1355 } | 1357 } |
1356 | 1358 |
1357 | 1359 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1416 const Object& result = | 1418 const Object& result = |
1417 PassiveObject::Handle(isolate->object_store()->sticky_error()); | 1419 PassiveObject::Handle(isolate->object_store()->sticky_error()); |
1418 isolate->object_store()->clear_sticky_error(); | 1420 isolate->object_store()->clear_sticky_error(); |
1419 return result.raw(); | 1421 return result.raw(); |
1420 } | 1422 } |
1421 UNREACHABLE(); | 1423 UNREACHABLE(); |
1422 return Object::null(); | 1424 return Object::null(); |
1423 } | 1425 } |
1424 | 1426 |
1425 } // namespace dart | 1427 } // namespace dart |
OLD | NEW |