| 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 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 const String& script_url = String::Handle(script.url()); | 202 const String& script_url = String::Handle(script.url()); |
| 203 // TODO(iposva): Extract script kind. | 203 // TODO(iposva): Extract script kind. |
| 204 THR_Print("Compiling %s '%s'\n", "", script_url.ToCString()); | 204 THR_Print("Compiling %s '%s'\n", "", script_url.ToCString()); |
| 205 } | 205 } |
| 206 const String& library_key = String::Handle(library.private_key()); | 206 const String& library_key = String::Handle(library.private_key()); |
| 207 script.Tokenize(library_key); | 207 script.Tokenize(library_key); |
| 208 Parser::ParseCompilationUnit(library, script); | 208 Parser::ParseCompilationUnit(library, script); |
| 209 return Error::null(); | 209 return Error::null(); |
| 210 } else { | 210 } else { |
| 211 Thread* const thread = Thread::Current(); | 211 Thread* const thread = Thread::Current(); |
| 212 Isolate* const isolate = thread->isolate(); | |
| 213 StackZone zone(thread); | 212 StackZone zone(thread); |
| 214 Error& error = Error::Handle(); | 213 Error& error = Error::Handle(); |
| 215 error = isolate->object_store()->sticky_error(); | 214 error = thread->sticky_error(); |
| 216 isolate->object_store()->clear_sticky_error(); | 215 thread->clear_sticky_error(); |
| 217 return error.raw(); | 216 return error.raw(); |
| 218 } | 217 } |
| 219 UNREACHABLE(); | 218 UNREACHABLE(); |
| 220 return Error::null(); | 219 return Error::null(); |
| 221 } | 220 } |
| 222 | 221 |
| 223 | 222 |
| 224 static void AddRelatedClassesToList( | 223 static void AddRelatedClassesToList( |
| 225 const Class& cls, | 224 const Class& cls, |
| 226 GrowableHandlePtrArray<const Class>* parse_list, | 225 GrowableHandlePtrArray<const Class>* parse_list, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 const Class& closure_cls = Class::Handle( | 284 const Class& closure_cls = Class::Handle( |
| 286 Isolate::Current()->object_store()->closure_class()); | 285 Isolate::Current()->object_store()->closure_class()); |
| 287 ASSERT(closure_cls.is_finalized()); | 286 ASSERT(closure_cls.is_finalized()); |
| 288 #endif | 287 #endif |
| 289 LongJumpScope jump; | 288 LongJumpScope jump; |
| 290 if (setjmp(*jump.Set()) == 0) { | 289 if (setjmp(*jump.Set()) == 0) { |
| 291 ClassFinalizer::FinalizeClass(cls); | 290 ClassFinalizer::FinalizeClass(cls); |
| 292 return Error::null(); | 291 return Error::null(); |
| 293 } else { | 292 } else { |
| 294 Thread* thread = Thread::Current(); | 293 Thread* thread = Thread::Current(); |
| 295 Isolate* isolate = thread->isolate(); | |
| 296 Error& error = Error::Handle(thread->zone()); | 294 Error& error = Error::Handle(thread->zone()); |
| 297 error = isolate->object_store()->sticky_error(); | 295 error = thread->sticky_error(); |
| 298 isolate->object_store()->clear_sticky_error(); | 296 thread->clear_sticky_error(); |
| 299 return error.raw(); | 297 return error.raw(); |
| 300 } | 298 } |
| 301 } | 299 } |
| 302 | 300 |
| 303 Thread* const thread = Thread::Current(); | 301 Thread* const thread = Thread::Current(); |
| 304 Isolate* const isolate = thread->isolate(); | |
| 305 StackZone zone(thread); | 302 StackZone zone(thread); |
| 306 // We remember all the classes that are being compiled in these lists. This | 303 // We remember all the classes that are being compiled in these lists. This |
| 307 // also allows us to reset the marked_for_parsing state in case we see an | 304 // also allows us to reset the marked_for_parsing state in case we see an |
| 308 // error. | 305 // error. |
| 309 VMTagScope tagScope(thread, VMTag::kCompileClassTagId); | 306 VMTagScope tagScope(thread, VMTag::kCompileClassTagId); |
| 310 TimelineDurationScope tds(thread, | 307 TimelineDurationScope tds(thread, |
| 311 thread->isolate()->GetCompilerStream(), | 308 thread->isolate()->GetCompilerStream(), |
| 312 "CompileClass"); | 309 "CompileClass"); |
| 313 if (tds.enabled()) { | 310 if (tds.enabled()) { |
| 314 tds.SetNumArguments(1); | 311 tds.SetNumArguments(1); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 parse_class.reset_is_marked_for_parsing(); | 375 parse_class.reset_is_marked_for_parsing(); |
| 379 } | 376 } |
| 380 } | 377 } |
| 381 for (intptr_t i = 0; i < patch_list.length(); i++) { | 378 for (intptr_t i = 0; i < patch_list.length(); i++) { |
| 382 const Class& parse_class = patch_list.At(i); | 379 const Class& parse_class = patch_list.At(i); |
| 383 if (parse_class.is_marked_for_parsing()) { | 380 if (parse_class.is_marked_for_parsing()) { |
| 384 parse_class.reset_is_marked_for_parsing(); | 381 parse_class.reset_is_marked_for_parsing(); |
| 385 } | 382 } |
| 386 } | 383 } |
| 387 Error& error = Error::Handle(zone.GetZone()); | 384 Error& error = Error::Handle(zone.GetZone()); |
| 388 error = isolate->object_store()->sticky_error(); | 385 error = thread->sticky_error(); |
| 389 isolate->object_store()->clear_sticky_error(); | 386 thread->clear_sticky_error(); |
| 390 return error.raw(); | 387 return error.raw(); |
| 391 } | 388 } |
| 392 UNREACHABLE(); | 389 UNREACHABLE(); |
| 393 return Error::null(); | 390 return Error::null(); |
| 394 } | 391 } |
| 395 | 392 |
| 396 | 393 |
| 397 class CompileParsedFunctionHelper : public ValueObject { | 394 class CompileParsedFunctionHelper : public ValueObject { |
| 398 public: | 395 public: |
| 399 CompileParsedFunctionHelper(ParsedFunction* parsed_function, | 396 CompileParsedFunctionHelper(ParsedFunction* parsed_function, |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1066 } | 1063 } |
| 1067 } | 1064 } |
| 1068 } | 1065 } |
| 1069 // Mark that this isolate now has compiled code. | 1066 // Mark that this isolate now has compiled code. |
| 1070 isolate()->set_has_compiled_code(true); | 1067 isolate()->set_has_compiled_code(true); |
| 1071 // Exit the loop and the function with the correct result value. | 1068 // Exit the loop and the function with the correct result value. |
| 1072 is_compiled = true; | 1069 is_compiled = true; |
| 1073 done = true; | 1070 done = true; |
| 1074 } else { | 1071 } else { |
| 1075 // We bailed out or we encountered an error. | 1072 // We bailed out or we encountered an error. |
| 1076 const Error& error = Error::Handle( | 1073 const Error& error = Error::Handle(thread()->sticky_error()); |
| 1077 isolate()->object_store()->sticky_error()); | |
| 1078 | 1074 |
| 1079 if (error.raw() == Object::branch_offset_error().raw()) { | 1075 if (error.raw() == Object::branch_offset_error().raw()) { |
| 1080 // Compilation failed due to an out of range branch offset in the | 1076 // Compilation failed due to an out of range branch offset in the |
| 1081 // assembler. We try again (done = false) with far branches enabled. | 1077 // assembler. We try again (done = false) with far branches enabled. |
| 1082 done = false; | 1078 done = false; |
| 1083 ASSERT(!use_far_branches); | 1079 ASSERT(!use_far_branches); |
| 1084 use_far_branches = true; | 1080 use_far_branches = true; |
| 1085 } else if (error.raw() == Object::speculative_inlining_error().raw()) { | 1081 } else if (error.raw() == Object::speculative_inlining_error().raw()) { |
| 1086 // The return value of setjmp is the deopt id of the check instruction | 1082 // The return value of setjmp is the deopt id of the check instruction |
| 1087 // that caused the bailout. | 1083 // that caused the bailout. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1108 // compiling (is_compiled = false). | 1104 // compiling (is_compiled = false). |
| 1109 if (FLAG_trace_bailout) { | 1105 if (FLAG_trace_bailout) { |
| 1110 THR_Print("%s\n", error.ToErrorCString()); | 1106 THR_Print("%s\n", error.ToErrorCString()); |
| 1111 } | 1107 } |
| 1112 done = true; | 1108 done = true; |
| 1113 } | 1109 } |
| 1114 | 1110 |
| 1115 // Clear the error if it was not a real error, but just a bailout. | 1111 // Clear the error if it was not a real error, but just a bailout. |
| 1116 if (error.IsLanguageError() && | 1112 if (error.IsLanguageError() && |
| 1117 (LanguageError::Cast(error).kind() == Report::kBailout)) { | 1113 (LanguageError::Cast(error).kind() == Report::kBailout)) { |
| 1118 isolate()->object_store()->clear_sticky_error(); | 1114 thread()->clear_sticky_error(); |
| 1119 } | 1115 } |
| 1120 is_compiled = false; | 1116 is_compiled = false; |
| 1121 } | 1117 } |
| 1122 // Reset global isolate state. | 1118 // Reset global isolate state. |
| 1123 thread()->set_deopt_id(prev_deopt_id); | 1119 thread()->set_deopt_id(prev_deopt_id); |
| 1124 } | 1120 } |
| 1125 return is_compiled; | 1121 return is_compiled; |
| 1126 } | 1122 } |
| 1127 | 1123 |
| 1128 | 1124 |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1346 } else if (FLAG_trace_failed_optimization_attempts) { | 1342 } else if (FLAG_trace_failed_optimization_attempts) { |
| 1347 THR_Print("Cannot optimize: %s\n", | 1343 THR_Print("Cannot optimize: %s\n", |
| 1348 function.ToFullyQualifiedCString()); | 1344 function.ToFullyQualifiedCString()); |
| 1349 } | 1345 } |
| 1350 function.SetIsOptimizable(false); | 1346 function.SetIsOptimizable(false); |
| 1351 return Error::null(); | 1347 return Error::null(); |
| 1352 } else { | 1348 } else { |
| 1353 // Encountered error. | 1349 // Encountered error. |
| 1354 Error& error = Error::Handle(); | 1350 Error& error = Error::Handle(); |
| 1355 // We got an error during compilation. | 1351 // We got an error during compilation. |
| 1356 error = isolate->object_store()->sticky_error(); | 1352 error = thread->sticky_error(); |
| 1357 isolate->object_store()->clear_sticky_error(); | 1353 thread->clear_sticky_error(); |
| 1358 ASSERT(error.IsLanguageError() && | 1354 ASSERT(error.IsLanguageError() && |
| 1359 LanguageError::Cast(error).kind() != Report::kBailout); | 1355 LanguageError::Cast(error).kind() != Report::kBailout); |
| 1360 return error.raw(); | 1356 return error.raw(); |
| 1361 } | 1357 } |
| 1362 } | 1358 } |
| 1363 | 1359 |
| 1364 per_compile_timer.Stop(); | 1360 per_compile_timer.Stop(); |
| 1365 | 1361 |
| 1366 if (trace_compiler && success) { | 1362 if (trace_compiler && success) { |
| 1367 THR_Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n", | 1363 THR_Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n", |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1384 THR_Print("*** BEGIN CODE\n"); | 1380 THR_Print("*** BEGIN CODE\n"); |
| 1385 DisassembleCode(function, true); | 1381 DisassembleCode(function, true); |
| 1386 THR_Print("*** END CODE\n"); | 1382 THR_Print("*** END CODE\n"); |
| 1387 } | 1383 } |
| 1388 #if defined(DEBUG) | 1384 #if defined(DEBUG) |
| 1389 CheckInliningIntervals(function); | 1385 CheckInliningIntervals(function); |
| 1390 #endif | 1386 #endif |
| 1391 return Error::null(); | 1387 return Error::null(); |
| 1392 } else { | 1388 } else { |
| 1393 Thread* const thread = Thread::Current(); | 1389 Thread* const thread = Thread::Current(); |
| 1394 Isolate* const isolate = thread->isolate(); | |
| 1395 StackZone stack_zone(thread); | 1390 StackZone stack_zone(thread); |
| 1396 Error& error = Error::Handle(); | 1391 Error& error = Error::Handle(); |
| 1397 // We got an error during compilation. | 1392 // We got an error during compilation. |
| 1398 error = isolate->object_store()->sticky_error(); | 1393 error = thread->sticky_error(); |
| 1399 isolate->object_store()->clear_sticky_error(); | 1394 thread->clear_sticky_error(); |
| 1400 // Unoptimized compilation or precompilation may encounter compile-time | 1395 // Unoptimized compilation or precompilation may encounter compile-time |
| 1401 // errors, but regular optimized compilation should not. | 1396 // errors, but regular optimized compilation should not. |
| 1402 ASSERT(!optimized || FLAG_precompilation); | 1397 ASSERT(!optimized || FLAG_precompilation); |
| 1403 // Do not attempt to optimize functions that can cause errors. | 1398 // Do not attempt to optimize functions that can cause errors. |
| 1404 function.set_is_optimizable(false); | 1399 function.set_is_optimizable(false); |
| 1405 return error.raw(); | 1400 return error.raw(); |
| 1406 } | 1401 } |
| 1407 UNREACHABLE(); | 1402 UNREACHABLE(); |
| 1408 return Error::null(); | 1403 return Error::null(); |
| 1409 } | 1404 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1495 if (setjmp(*jump.Set()) == 0) { | 1490 if (setjmp(*jump.Set()) == 0) { |
| 1496 // Non-optimized code generator. | 1491 // Non-optimized code generator. |
| 1497 DartCompilationPipeline pipeline; | 1492 DartCompilationPipeline pipeline; |
| 1498 CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId); | 1493 CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId); |
| 1499 helper.Compile(&pipeline); | 1494 helper.Compile(&pipeline); |
| 1500 if (FLAG_disassemble) { | 1495 if (FLAG_disassemble) { |
| 1501 DisassembleCode(parsed_function->function(), false); | 1496 DisassembleCode(parsed_function->function(), false); |
| 1502 } | 1497 } |
| 1503 return Error::null(); | 1498 return Error::null(); |
| 1504 } else { | 1499 } else { |
| 1505 Isolate* const isolate = Isolate::Current(); | |
| 1506 Error& error = Error::Handle(); | 1500 Error& error = Error::Handle(); |
| 1501 Thread* thread = Thread::Current(); |
| 1507 // We got an error during compilation. | 1502 // We got an error during compilation. |
| 1508 error = isolate->object_store()->sticky_error(); | 1503 error = thread->sticky_error(); |
| 1509 isolate->object_store()->clear_sticky_error(); | 1504 thread->clear_sticky_error(); |
| 1510 return error.raw(); | 1505 return error.raw(); |
| 1511 } | 1506 } |
| 1512 UNREACHABLE(); | 1507 UNREACHABLE(); |
| 1513 return Error::null(); | 1508 return Error::null(); |
| 1514 } | 1509 } |
| 1515 | 1510 |
| 1516 | 1511 |
| 1517 void Compiler::ComputeLocalVarDescriptors(const Code& code) { | 1512 void Compiler::ComputeLocalVarDescriptors(const Code& code) { |
| 1518 ASSERT(!code.is_optimized()); | 1513 ASSERT(!code.is_optimized()); |
| 1519 const Function& function = Function::Handle(code.function()); | 1514 const Function& function = Function::Handle(code.function()); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1614 initializer = parsed_function->function().raw(); | 1609 initializer = parsed_function->function().raw(); |
| 1615 Code::Handle(initializer.unoptimized_code()).set_var_descriptors( | 1610 Code::Handle(initializer.unoptimized_code()).set_var_descriptors( |
| 1616 Object::empty_var_descriptors()); | 1611 Object::empty_var_descriptors()); |
| 1617 } else { | 1612 } else { |
| 1618 initializer ^= field.PrecompiledInitializer(); | 1613 initializer ^= field.PrecompiledInitializer(); |
| 1619 } | 1614 } |
| 1620 // Invoke the function to evaluate the expression. | 1615 // Invoke the function to evaluate the expression. |
| 1621 return DartEntry::InvokeFunction(initializer, Object::empty_array()); | 1616 return DartEntry::InvokeFunction(initializer, Object::empty_array()); |
| 1622 } else { | 1617 } else { |
| 1623 Thread* const thread = Thread::Current(); | 1618 Thread* const thread = Thread::Current(); |
| 1624 Isolate* const isolate = thread->isolate(); | |
| 1625 StackZone zone(thread); | 1619 StackZone zone(thread); |
| 1626 const Error& error = | 1620 const Error& error = Error::Handle(thread->zone(), thread->sticky_error()); |
| 1627 Error::Handle(thread->zone(), isolate->object_store()->sticky_error()); | 1621 thread->clear_sticky_error(); |
| 1628 isolate->object_store()->clear_sticky_error(); | |
| 1629 return error.raw(); | 1622 return error.raw(); |
| 1630 } | 1623 } |
| 1631 UNREACHABLE(); | 1624 UNREACHABLE(); |
| 1632 return Object::null(); | 1625 return Object::null(); |
| 1633 } | 1626 } |
| 1634 | 1627 |
| 1635 | 1628 |
| 1636 | 1629 |
| 1637 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { | 1630 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { |
| 1638 LongJumpScope jump; | 1631 LongJumpScope jump; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1680 CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId); | 1673 CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId); |
| 1681 helper.Compile(&pipeline); | 1674 helper.Compile(&pipeline); |
| 1682 Code::Handle(func.unoptimized_code()).set_var_descriptors( | 1675 Code::Handle(func.unoptimized_code()).set_var_descriptors( |
| 1683 Object::empty_var_descriptors()); | 1676 Object::empty_var_descriptors()); |
| 1684 | 1677 |
| 1685 const Object& result = PassiveObject::Handle( | 1678 const Object& result = PassiveObject::Handle( |
| 1686 DartEntry::InvokeFunction(func, Object::empty_array())); | 1679 DartEntry::InvokeFunction(func, Object::empty_array())); |
| 1687 return result.raw(); | 1680 return result.raw(); |
| 1688 } else { | 1681 } else { |
| 1689 Thread* const thread = Thread::Current(); | 1682 Thread* const thread = Thread::Current(); |
| 1690 Isolate* const isolate = thread->isolate(); | 1683 const Object& result = PassiveObject::Handle(thread->sticky_error()); |
| 1691 const Object& result = | 1684 thread->clear_sticky_error(); |
| 1692 PassiveObject::Handle(isolate->object_store()->sticky_error()); | |
| 1693 isolate->object_store()->clear_sticky_error(); | |
| 1694 return result.raw(); | 1685 return result.raw(); |
| 1695 } | 1686 } |
| 1696 UNREACHABLE(); | 1687 UNREACHABLE(); |
| 1697 return Object::null(); | 1688 return Object::null(); |
| 1698 } | 1689 } |
| 1699 | 1690 |
| 1700 | 1691 |
| 1701 // C-heap allocated background compilation queue element. | 1692 // C-heap allocated background compilation queue element. |
| 1702 class QueueElement { | 1693 class QueueElement { |
| 1703 public: | 1694 public: |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2044 } | 2035 } |
| 2045 | 2036 |
| 2046 | 2037 |
| 2047 void BackgroundCompiler::EnsureInit(Thread* thread) { | 2038 void BackgroundCompiler::EnsureInit(Thread* thread) { |
| 2048 UNREACHABLE(); | 2039 UNREACHABLE(); |
| 2049 } | 2040 } |
| 2050 | 2041 |
| 2051 #endif // DART_PRECOMPILED_RUNTIME | 2042 #endif // DART_PRECOMPILED_RUNTIME |
| 2052 | 2043 |
| 2053 } // namespace dart | 2044 } // namespace dart |
| OLD | NEW |