Chromium Code Reviews| 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 1356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1367 } | 1367 } |
| 1368 // Do not attempt to optimize functions that can cause errors. | 1368 // Do not attempt to optimize functions that can cause errors. |
| 1369 function.set_is_optimizable(false); | 1369 function.set_is_optimizable(false); |
| 1370 return error.raw(); | 1370 return error.raw(); |
| 1371 } | 1371 } |
| 1372 UNREACHABLE(); | 1372 UNREACHABLE(); |
| 1373 return Error::null(); | 1373 return Error::null(); |
| 1374 } | 1374 } |
| 1375 | 1375 |
| 1376 | 1376 |
| 1377 static RawError* ParseFunctionHelper(CompilationPipeline* pipeline, | |
| 1378 const Function& function, | |
| 1379 bool optimized, | |
| 1380 intptr_t osr_id) { | |
| 1381 ASSERT(!FLAG_precompiled_mode); | |
| 1382 ASSERT(!optimized || function.was_compiled()); | |
| 1383 LongJumpScope jump; | |
| 1384 if (setjmp(*jump.Set()) == 0) { | |
| 1385 Thread* const thread = Thread::Current(); | |
| 1386 StackZone stack_zone(thread); | |
| 1387 Zone* const zone = stack_zone.GetZone(); | |
| 1388 const bool trace_compiler = | |
| 1389 FLAG_trace_compiler || | |
| 1390 (FLAG_trace_optimizing_compiler && optimized); | |
| 1391 | |
| 1392 if (trace_compiler) { | |
| 1393 const intptr_t token_size = function.end_token_pos().Pos() - | |
| 1394 function.token_pos().Pos(); | |
| 1395 THR_Print("Parsing %s%sfunction %s: '%s' @ token %s, size %" Pd "\n", | |
| 1396 (osr_id == Compiler::kNoOSRDeoptId ? "" : "osr "), | |
| 1397 (optimized ? "optimized " : ""), | |
| 1398 (Compiler::IsBackgroundCompilation() ? "(background)" : ""), | |
| 1399 function.ToFullyQualifiedCString(), | |
| 1400 function.token_pos().ToCString(), | |
| 1401 token_size); | |
| 1402 } | |
| 1403 ParsedFunction* parsed_function = new(zone) ParsedFunction( | |
| 1404 thread, Function::ZoneHandle(zone, function.raw())); | |
| 1405 pipeline->ParseFunction(parsed_function); | |
| 1406 // For now we just walk thru the AST nodes and in DEBUG mode we print | |
| 1407 // them otherwise just skip through them, this will be need to be | |
| 1408 // wired to generate the IR format. | |
| 1409 #if defined(DEBUG) | |
| 1410 AstPrinter ast_printer(true); | |
| 1411 #else | |
| 1412 AstPrinter ast_printer(false); | |
|
hausner
2016/09/23 21:57:20
What's the purpose of invoking the ast printer vis
siva
2016/09/23 22:05:36
I wanted to keep it to measure if traversing the A
| |
| 1413 #endif // defined(DEBUG). | |
| 1414 ast_printer.PrintFunctionNodes(*parsed_function); | |
| 1415 return Error::null(); | |
| 1416 } else { | |
| 1417 Thread* const thread = Thread::Current(); | |
| 1418 StackZone stack_zone(thread); | |
| 1419 Error& error = Error::Handle(); | |
| 1420 // We got an error during compilation or it is a bailout from background | |
| 1421 // compilation (e.g., during parsing with EnsureIsFinalized). | |
| 1422 error = thread->sticky_error(); | |
| 1423 thread->clear_sticky_error(); | |
| 1424 // Unoptimized compilation or precompilation may encounter compile-time | |
| 1425 // errors, but regular optimized compilation should not. | |
| 1426 ASSERT(!optimized); | |
| 1427 return error.raw(); | |
| 1428 } | |
| 1429 UNREACHABLE(); | |
| 1430 return Error::null(); | |
| 1431 } | |
| 1432 | |
| 1433 | |
| 1377 RawError* Compiler::CompileFunction(Thread* thread, | 1434 RawError* Compiler::CompileFunction(Thread* thread, |
| 1378 const Function& function) { | 1435 const Function& function) { |
| 1379 #ifdef DART_PRECOMPILER | 1436 #ifdef DART_PRECOMPILER |
| 1380 if (FLAG_precompiled_mode) { | 1437 if (FLAG_precompiled_mode) { |
| 1381 return Precompiler::CompileFunction(thread, thread->zone(), function); | 1438 return Precompiler::CompileFunction(thread, thread->zone(), function); |
| 1382 } | 1439 } |
| 1383 #endif | 1440 #endif |
| 1384 Isolate* isolate = thread->isolate(); | 1441 Isolate* isolate = thread->isolate(); |
| 1385 NOT_IN_PRODUCT( | 1442 NOT_IN_PRODUCT( |
| 1386 VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId); | 1443 VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1397 CompilationPipeline* pipeline = | 1454 CompilationPipeline* pipeline = |
| 1398 CompilationPipeline::New(thread->zone(), function); | 1455 CompilationPipeline::New(thread->zone(), function); |
| 1399 | 1456 |
| 1400 return CompileFunctionHelper(pipeline, | 1457 return CompileFunctionHelper(pipeline, |
| 1401 function, | 1458 function, |
| 1402 /* optimized = */ false, | 1459 /* optimized = */ false, |
| 1403 kNoOSRDeoptId); | 1460 kNoOSRDeoptId); |
| 1404 } | 1461 } |
| 1405 | 1462 |
| 1406 | 1463 |
| 1464 RawError* Compiler::ParseFunction(Thread* thread, | |
| 1465 const Function& function) { | |
| 1466 Isolate* isolate = thread->isolate(); | |
| 1467 NOT_IN_PRODUCT( | |
| 1468 VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId); | |
| 1469 TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "ParseFunction", function); | |
| 1470 ) // !PRODUCT | |
| 1471 | |
| 1472 if (!isolate->compilation_allowed()) { | |
| 1473 FATAL3("Precompilation missed function %s (%s, %s)\n", | |
| 1474 function.ToLibNamePrefixedQualifiedCString(), | |
| 1475 function.token_pos().ToCString(), | |
| 1476 Function::KindToCString(function.kind())); | |
| 1477 } | |
| 1478 | |
| 1479 CompilationPipeline* pipeline = | |
| 1480 CompilationPipeline::New(thread->zone(), function); | |
| 1481 | |
| 1482 return ParseFunctionHelper(pipeline, | |
| 1483 function, | |
| 1484 /* optimized = */ false, | |
| 1485 kNoOSRDeoptId); | |
| 1486 } | |
| 1487 | |
| 1488 | |
| 1407 RawError* Compiler::EnsureUnoptimizedCode(Thread* thread, | 1489 RawError* Compiler::EnsureUnoptimizedCode(Thread* thread, |
| 1408 const Function& function) { | 1490 const Function& function) { |
| 1409 if (function.unoptimized_code() != Object::null()) { | 1491 if (function.unoptimized_code() != Object::null()) { |
| 1410 return Error::null(); | 1492 return Error::null(); |
| 1411 } | 1493 } |
| 1412 Code& original_code = Code::ZoneHandle(thread->zone()); | 1494 Code& original_code = Code::ZoneHandle(thread->zone()); |
| 1413 if (function.HasCode()) { | 1495 if (function.HasCode()) { |
| 1414 original_code = function.CurrentCode(); | 1496 original_code = function.CurrentCode(); |
| 1415 } | 1497 } |
| 1416 CompilationPipeline* pipeline = | 1498 CompilationPipeline* pipeline = |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1548 return error.raw(); | 1630 return error.raw(); |
| 1549 } | 1631 } |
| 1550 func.ClearICDataArray(); | 1632 func.ClearICDataArray(); |
| 1551 func.ClearCode(); | 1633 func.ClearCode(); |
| 1552 } | 1634 } |
| 1553 } | 1635 } |
| 1554 return error.raw(); | 1636 return error.raw(); |
| 1555 } | 1637 } |
| 1556 | 1638 |
| 1557 | 1639 |
| 1640 RawError* Compiler::ParseAllFunctions(const Class& cls) { | |
| 1641 Thread* thread = Thread::Current(); | |
| 1642 Zone* zone = thread->zone(); | |
| 1643 Error& error = Error::Handle(zone); | |
| 1644 Array& functions = Array::Handle(zone, cls.functions()); | |
| 1645 Function& func = Function::Handle(zone); | |
| 1646 // Class dynamic lives in the vm isolate. Its array fields cannot be set to | |
| 1647 // an empty array. | |
| 1648 if (functions.IsNull()) { | |
| 1649 ASSERT(cls.IsDynamicClass()); | |
| 1650 return error.raw(); | |
| 1651 } | |
| 1652 // Compile all the regular functions. | |
| 1653 for (int i = 0; i < functions.Length(); i++) { | |
| 1654 func ^= functions.At(i); | |
| 1655 ASSERT(!func.IsNull()); | |
| 1656 if (!func.is_abstract() && !func.IsRedirectingFactory()) { | |
| 1657 if ((cls.is_mixin_app_alias() || cls.IsMixinApplication()) && | |
| 1658 func.HasOptionalParameters()) { | |
| 1659 // Skipping optional parameters in mixin application. | |
| 1660 continue; | |
| 1661 } | |
| 1662 error = ParseFunction(thread, func); | |
| 1663 if (!error.IsNull()) { | |
| 1664 return error.raw(); | |
| 1665 } | |
| 1666 func.ClearICDataArray(); | |
| 1667 func.ClearCode(); | |
| 1668 } | |
| 1669 } | |
| 1670 return error.raw(); | |
| 1671 } | |
| 1672 | |
| 1673 | |
| 1558 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { | 1674 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { |
| 1559 #ifdef DART_PRECOMPILER | 1675 #ifdef DART_PRECOMPILER |
| 1560 if (FLAG_precompiled_mode) { | 1676 if (FLAG_precompiled_mode) { |
| 1561 return Precompiler::EvaluateStaticInitializer(field); | 1677 return Precompiler::EvaluateStaticInitializer(field); |
| 1562 } | 1678 } |
| 1563 #endif | 1679 #endif |
| 1564 ASSERT(field.is_static()); | 1680 ASSERT(field.is_static()); |
| 1565 // The VM sets the field's value to transiton_sentinel prior to | 1681 // The VM sets the field's value to transiton_sentinel prior to |
| 1566 // evaluating the initializer value. | 1682 // evaluating the initializer value. |
| 1567 ASSERT(field.StaticValue() == Object::transition_sentinel().raw()); | 1683 ASSERT(field.StaticValue() == Object::transition_sentinel().raw()); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1626 // Don't allow message interrupts while executing constant | 1742 // Don't allow message interrupts while executing constant |
| 1627 // expressions. They can cause bogus recursive compilation. | 1743 // expressions. They can cause bogus recursive compilation. |
| 1628 NoOOBMessageScope no_msg_scope(thread); | 1744 NoOOBMessageScope no_msg_scope(thread); |
| 1629 | 1745 |
| 1630 // Don't allow reload requests to come in. | 1746 // Don't allow reload requests to come in. |
| 1631 NoReloadScope no_reload_scope(thread->isolate(), thread); | 1747 NoReloadScope no_reload_scope(thread->isolate(), thread); |
| 1632 | 1748 |
| 1633 if (FLAG_trace_compiler) { | 1749 if (FLAG_trace_compiler) { |
| 1634 THR_Print("compiling expression: "); | 1750 THR_Print("compiling expression: "); |
| 1635 if (FLAG_support_ast_printer) { | 1751 if (FLAG_support_ast_printer) { |
| 1636 AstPrinter::PrintNode(fragment); | 1752 AstPrinter ast_printer; |
| 1753 ast_printer.PrintNode(fragment); | |
| 1637 } | 1754 } |
| 1638 } | 1755 } |
| 1639 | 1756 |
| 1640 // Create a dummy function object for the code generator. | 1757 // Create a dummy function object for the code generator. |
| 1641 // The function needs to be associated with a named Class: the interface | 1758 // The function needs to be associated with a named Class: the interface |
| 1642 // Function fits the bill. | 1759 // Function fits the bill. |
| 1643 const char* kEvalConst = "eval_const"; | 1760 const char* kEvalConst = "eval_const"; |
| 1644 const Function& func = Function::ZoneHandle(Function::New( | 1761 const Function& func = Function::ZoneHandle(Function::New( |
| 1645 String::Handle(Symbols::New(thread, kEvalConst)), | 1762 String::Handle(Symbols::New(thread, kEvalConst)), |
| 1646 RawFunction::kRegularFunction, | 1763 RawFunction::kRegularFunction, |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2084 } | 2201 } |
| 2085 | 2202 |
| 2086 | 2203 |
| 2087 RawError* Compiler::CompileFunction(Thread* thread, | 2204 RawError* Compiler::CompileFunction(Thread* thread, |
| 2088 const Function& function) { | 2205 const Function& function) { |
| 2089 UNREACHABLE(); | 2206 UNREACHABLE(); |
| 2090 return Error::null(); | 2207 return Error::null(); |
| 2091 } | 2208 } |
| 2092 | 2209 |
| 2093 | 2210 |
| 2211 RawError* Compiler::ParseFunction(Thread* thread, | |
| 2212 const Function& function) { | |
| 2213 UNREACHABLE(); | |
| 2214 return Error::null(); | |
| 2215 } | |
| 2216 | |
| 2217 | |
| 2094 RawError* Compiler::EnsureUnoptimizedCode(Thread* thread, | 2218 RawError* Compiler::EnsureUnoptimizedCode(Thread* thread, |
| 2095 const Function& function) { | 2219 const Function& function) { |
| 2096 UNREACHABLE(); | 2220 UNREACHABLE(); |
| 2097 return Error::null(); | 2221 return Error::null(); |
| 2098 } | 2222 } |
| 2099 | 2223 |
| 2100 | 2224 |
| 2101 RawError* Compiler::CompileOptimizedFunction(Thread* thread, | 2225 RawError* Compiler::CompileOptimizedFunction(Thread* thread, |
| 2102 const Function& function, | 2226 const Function& function, |
| 2103 intptr_t osr_id) { | 2227 intptr_t osr_id) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 2117 UNREACHABLE(); | 2241 UNREACHABLE(); |
| 2118 } | 2242 } |
| 2119 | 2243 |
| 2120 | 2244 |
| 2121 RawError* Compiler::CompileAllFunctions(const Class& cls) { | 2245 RawError* Compiler::CompileAllFunctions(const Class& cls) { |
| 2122 UNREACHABLE(); | 2246 UNREACHABLE(); |
| 2123 return Error::null(); | 2247 return Error::null(); |
| 2124 } | 2248 } |
| 2125 | 2249 |
| 2126 | 2250 |
| 2251 RawError* Compiler::ParseAllFunctions(const Class& cls) { | |
| 2252 UNREACHABLE(); | |
| 2253 return Error::null(); | |
| 2254 } | |
| 2255 | |
| 2256 | |
| 2127 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { | 2257 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) { |
| 2128 ASSERT(field.HasPrecompiledInitializer()); | 2258 ASSERT(field.HasPrecompiledInitializer()); |
| 2129 const Function& initializer = | 2259 const Function& initializer = |
| 2130 Function::Handle(field.PrecompiledInitializer()); | 2260 Function::Handle(field.PrecompiledInitializer()); |
| 2131 return DartEntry::InvokeFunction(initializer, Object::empty_array()); | 2261 return DartEntry::InvokeFunction(initializer, Object::empty_array()); |
| 2132 } | 2262 } |
| 2133 | 2263 |
| 2134 | 2264 |
| 2135 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { | 2265 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) { |
| 2136 UNREACHABLE(); | 2266 UNREACHABLE(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2174 | 2304 |
| 2175 | 2305 |
| 2176 bool BackgroundCompiler::IsDisabled() { | 2306 bool BackgroundCompiler::IsDisabled() { |
| 2177 UNREACHABLE(); | 2307 UNREACHABLE(); |
| 2178 return true; | 2308 return true; |
| 2179 } | 2309 } |
| 2180 | 2310 |
| 2181 #endif // DART_PRECOMPILED_RUNTIME | 2311 #endif // DART_PRECOMPILED_RUNTIME |
| 2182 | 2312 |
| 2183 } // namespace dart | 2313 } // namespace dart |
| OLD | NEW |