| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 <map> | 5 #include <map> |
| 6 #include <set> | 6 #include <set> |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "vm/kernel_to_il.h" | 9 #include "vm/kernel_to_il.h" |
| 10 | 10 |
| (...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1312 | 1312 |
| 1313 ConstantEvaluator::ConstantEvaluator(FlowGraphBuilder* builder, | 1313 ConstantEvaluator::ConstantEvaluator(FlowGraphBuilder* builder, |
| 1314 Zone* zone, | 1314 Zone* zone, |
| 1315 TranslationHelper* h, | 1315 TranslationHelper* h, |
| 1316 DartTypeTranslator* type_translator) | 1316 DartTypeTranslator* type_translator) |
| 1317 : builder_(builder), | 1317 : builder_(builder), |
| 1318 isolate_(Isolate::Current()), | 1318 isolate_(Isolate::Current()), |
| 1319 zone_(zone), | 1319 zone_(zone), |
| 1320 translation_helper_(*h), | 1320 translation_helper_(*h), |
| 1321 type_translator_(*type_translator), | 1321 type_translator_(*type_translator), |
| 1322 script_(dart::Script::Handle( | 1322 script_(Script::Handle( |
| 1323 zone, | 1323 zone, |
| 1324 builder_->parsed_function_->function().script())), | 1324 builder == NULL ? Script::null() |
| 1325 result_(dart::Instance::Handle(zone)) {} | 1325 : builder_->parsed_function_->function().script())), |
| 1326 result_(Instance::Handle(zone)) {} |
| 1326 | 1327 |
| 1327 | 1328 |
| 1328 Instance& ConstantEvaluator::EvaluateExpression(Expression* expression) { | 1329 Instance& ConstantEvaluator::EvaluateExpression(Expression* expression) { |
| 1329 if (!GetCachedConstant(expression, &result_)) { | 1330 if (!GetCachedConstant(expression, &result_)) { |
| 1330 expression->AcceptExpressionVisitor(this); | 1331 expression->AcceptExpressionVisitor(this); |
| 1331 CacheConstantValue(expression, result_); | 1332 CacheConstantValue(expression, result_); |
| 1332 } | 1333 } |
| 1333 // We return a new `ZoneHandle` here on purpose: The intermediate language | 1334 // We return a new `ZoneHandle` here on purpose: The intermediate language |
| 1334 // instructions do not make a copy of the handle, so we do it. | 1335 // instructions do not make a copy of the handle, so we do it. |
| 1335 return dart::Instance::ZoneHandle(Z, result_.raw()); | 1336 return dart::Instance::ZoneHandle(Z, result_.raw()); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1461 ASSERT(!result.IsError()); | 1462 ASSERT(!result.IsError()); |
| 1462 if (constructor.IsFactory()) { | 1463 if (constructor.IsFactory()) { |
| 1463 // The factory method returns the allocated object. | 1464 // The factory method returns the allocated object. |
| 1464 instance ^= result.raw(); | 1465 instance ^= result.raw(); |
| 1465 } | 1466 } |
| 1466 return H.Canonicalize(instance); | 1467 return H.Canonicalize(instance); |
| 1467 } | 1468 } |
| 1468 | 1469 |
| 1469 | 1470 |
| 1470 bool ConstantEvaluator::GetCachedConstant(TreeNode* node, Instance* value) { | 1471 bool ConstantEvaluator::GetCachedConstant(TreeNode* node, Instance* value) { |
| 1472 if (builder_ == NULL) return false; |
| 1473 |
| 1471 const Function& function = builder_->parsed_function_->function(); | 1474 const Function& function = builder_->parsed_function_->function(); |
| 1472 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) { | 1475 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) { |
| 1473 // Don't cache constants in initializer expressions. They get | 1476 // Don't cache constants in initializer expressions. They get |
| 1474 // evaluated only once. | 1477 // evaluated only once. |
| 1475 return false; | 1478 return false; |
| 1476 } | 1479 } |
| 1477 | 1480 |
| 1478 bool is_present = false; | 1481 bool is_present = false; |
| 1479 ASSERT(!script_.InVMHeap()); | 1482 ASSERT(!script_.InVMHeap()); |
| 1480 if (script_.compile_time_constants() == Array::null()) { | 1483 if (script_.compile_time_constants() == Array::null()) { |
| 1481 return false; | 1484 return false; |
| 1482 } | 1485 } |
| 1483 KernelConstantsMap constants(script_.compile_time_constants()); | 1486 KernelConstantsMap constants(script_.compile_time_constants()); |
| 1484 *value ^= constants.GetOrNull(node, &is_present); | 1487 *value ^= constants.GetOrNull(node, &is_present); |
| 1485 // Mutator compiler thread may add constants while background compiler | 1488 // Mutator compiler thread may add constants while background compiler |
| 1486 // is running, and thus change the value of 'compile_time_constants'; | 1489 // is running, and thus change the value of 'compile_time_constants'; |
| 1487 // do not assert that 'compile_time_constants' has not changed. | 1490 // do not assert that 'compile_time_constants' has not changed. |
| 1488 constants.Release(); | 1491 constants.Release(); |
| 1489 if (FLAG_compiler_stats && is_present) { | 1492 if (FLAG_compiler_stats && is_present) { |
| 1490 H.thread()->compiler_stats()->num_const_cache_hits++; | 1493 H.thread()->compiler_stats()->num_const_cache_hits++; |
| 1491 } | 1494 } |
| 1492 return is_present; | 1495 return is_present; |
| 1493 } | 1496 } |
| 1494 | 1497 |
| 1495 | 1498 |
| 1496 void ConstantEvaluator::CacheConstantValue(TreeNode* node, | 1499 void ConstantEvaluator::CacheConstantValue(TreeNode* node, |
| 1497 const Instance& value) { | 1500 const Instance& value) { |
| 1498 ASSERT(Thread::Current()->IsMutatorThread()); | 1501 ASSERT(Thread::Current()->IsMutatorThread()); |
| 1499 | 1502 |
| 1503 if (builder_ == NULL) return; |
| 1504 |
| 1500 const Function& function = builder_->parsed_function_->function(); | 1505 const Function& function = builder_->parsed_function_->function(); |
| 1501 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) { | 1506 if (function.kind() == RawFunction::kImplicitStaticFinalGetter) { |
| 1502 // Don't cache constants in initializer expressions. They get | 1507 // Don't cache constants in initializer expressions. They get |
| 1503 // evaluated only once. | 1508 // evaluated only once. |
| 1504 return; | 1509 return; |
| 1505 } | 1510 } |
| 1506 const intptr_t kInitialConstMapSize = 16; | 1511 const intptr_t kInitialConstMapSize = 16; |
| 1507 ASSERT(!script_.InVMHeap()); | 1512 ASSERT(!script_.InVMHeap()); |
| 1508 if (script_.compile_time_constants() == Array::null()) { | 1513 if (script_.compile_time_constants() == Array::null()) { |
| 1509 const Array& array = Array::Handle( | 1514 const Array& array = Array::Handle( |
| (...skipping 4404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5914 instructions += StoreInstanceField(Closure::function_offset()); | 5919 instructions += StoreInstanceField(Closure::function_offset()); |
| 5915 | 5920 |
| 5916 instructions += LoadLocal(closure); | 5921 instructions += LoadLocal(closure); |
| 5917 instructions += LoadLocal(parsed_function_->current_context_var()); | 5922 instructions += LoadLocal(parsed_function_->current_context_var()); |
| 5918 instructions += StoreInstanceField(Closure::context_offset()); | 5923 instructions += StoreInstanceField(Closure::context_offset()); |
| 5919 | 5924 |
| 5920 return instructions; | 5925 return instructions; |
| 5921 } | 5926 } |
| 5922 | 5927 |
| 5923 | 5928 |
| 5929 RawObject* EvaluateMetadata(TreeNode* kernel_node) { |
| 5930 LongJumpScope jump; |
| 5931 if (setjmp(*jump.Set()) == 0) { |
| 5932 Thread* thread = Thread::Current(); |
| 5933 Zone* zone_ = thread->zone(); |
| 5934 |
| 5935 List<Expression>* metadata_expressions = NULL; |
| 5936 if (kernel_node->IsClass()) { |
| 5937 metadata_expressions = &Class::Cast(kernel_node)->annotations(); |
| 5938 } else if (kernel_node->IsProcedure()) { |
| 5939 metadata_expressions = &Procedure::Cast(kernel_node)->annotations(); |
| 5940 } else if (kernel_node->IsField()) { |
| 5941 metadata_expressions = &Field::Cast(kernel_node)->annotations(); |
| 5942 } else if (kernel_node->IsConstructor()) { |
| 5943 metadata_expressions = &Constructor::Cast(kernel_node)->annotations(); |
| 5944 } else { |
| 5945 FATAL1("No support for metadata on this type of kernel node %p\n", |
| 5946 kernel_node); |
| 5947 } |
| 5948 |
| 5949 TranslationHelper translation_helper(thread); |
| 5950 DartTypeTranslator type_translator(&translation_helper, NULL, true); |
| 5951 ConstantEvaluator constant_evaluator(/* flow_graph_builder = */ NULL, Z, |
| 5952 &translation_helper, &type_translator); |
| 5953 |
| 5954 const Array& metadata_values = |
| 5955 Array::Handle(Z, Array::New(metadata_expressions->length())); |
| 5956 |
| 5957 for (intptr_t i = 0; i < metadata_expressions->length(); i++) { |
| 5958 const Instance& value = |
| 5959 constant_evaluator.EvaluateExpression((*metadata_expressions)[i]); |
| 5960 metadata_values.SetAt(i, value); |
| 5961 } |
| 5962 |
| 5963 return metadata_values.raw(); |
| 5964 } else { |
| 5965 Thread* thread = Thread::Current(); |
| 5966 Error& error = Error::Handle(); |
| 5967 error = thread->sticky_error(); |
| 5968 thread->clear_sticky_error(); |
| 5969 return error.raw(); |
| 5970 } |
| 5971 } |
| 5972 |
| 5973 |
| 5974 RawObject* BuildParameterDescriptor(TreeNode* kernel_node) { |
| 5975 LongJumpScope jump; |
| 5976 if (setjmp(*jump.Set()) == 0) { |
| 5977 FunctionNode* function_node = NULL; |
| 5978 |
| 5979 if (kernel_node->IsProcedure()) { |
| 5980 function_node = Procedure::Cast(kernel_node)->function(); |
| 5981 } else if (kernel_node->IsConstructor()) { |
| 5982 function_node = Constructor::Cast(kernel_node)->function(); |
| 5983 } else if (kernel_node->IsFunctionNode()) { |
| 5984 function_node = FunctionNode::Cast(kernel_node); |
| 5985 } else { |
| 5986 UNIMPLEMENTED(); |
| 5987 return NULL; |
| 5988 } |
| 5989 |
| 5990 Thread* thread = Thread::Current(); |
| 5991 Zone* zone_ = thread->zone(); |
| 5992 TranslationHelper translation_helper(thread); |
| 5993 DartTypeTranslator type_translator(&translation_helper, NULL, true); |
| 5994 ConstantEvaluator constant_evaluator(/* flow_graph_builder = */ NULL, Z, |
| 5995 &translation_helper, &type_translator); |
| 5996 |
| 5997 |
| 5998 intptr_t param_count = function_node->positional_parameters().length() + |
| 5999 function_node->named_parameters().length(); |
| 6000 const Array& param_descriptor = Array::Handle( |
| 6001 Array::New(param_count * Parser::kParameterEntrySize, Heap::kOld)); |
| 6002 for (intptr_t i = 0; i < param_count; ++i) { |
| 6003 VariableDeclaration* variable; |
| 6004 if (i < function_node->positional_parameters().length()) { |
| 6005 variable = function_node->positional_parameters()[i]; |
| 6006 } else { |
| 6007 variable = function_node->named_parameters()[i]; |
| 6008 } |
| 6009 |
| 6010 param_descriptor.SetAt( |
| 6011 i + Parser::kParameterIsFinalOffset, |
| 6012 variable->IsFinal() ? Bool::True() : Bool::False()); |
| 6013 |
| 6014 if (variable->initializer() != NULL) { |
| 6015 param_descriptor.SetAt( |
| 6016 i + Parser::kParameterDefaultValueOffset, |
| 6017 constant_evaluator.EvaluateExpression(variable->initializer())); |
| 6018 } else { |
| 6019 param_descriptor.SetAt(i + Parser::kParameterDefaultValueOffset, |
| 6020 Object::null_instance()); |
| 6021 } |
| 6022 |
| 6023 param_descriptor.SetAt(i + Parser::kParameterMetadataOffset, |
| 6024 /* Issue(28434): Missing parameter metadata. */ |
| 6025 Object::null_instance()); |
| 6026 } |
| 6027 return param_descriptor.raw(); |
| 6028 } else { |
| 6029 Thread* thread = Thread::Current(); |
| 6030 Error& error = Error::Handle(); |
| 6031 error = thread->sticky_error(); |
| 6032 thread->clear_sticky_error(); |
| 6033 return error.raw(); |
| 6034 } |
| 6035 } |
| 6036 |
| 6037 |
| 5924 } // namespace kernel | 6038 } // namespace kernel |
| 5925 } // namespace dart | 6039 } // namespace dart |
| 6040 |
| 5926 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 6041 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| OLD | NEW |