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