Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(570)

Unified Diff: runtime/vm/parser.cc

Issue 2338463003: Improve compile time constant evaluation (Closed)
Patch Set: Merge branch 'master' into ponly Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/compiler_stats.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 4134d2b372207b21b0bd4239a895b599a22d61b5..7c5eefc23cf71e9f26f2671a059eb86940ddaf34 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -2730,12 +2730,7 @@ AstNode* Parser::ParseInitializer(const Class& cls,
if (init_expr->EvalConstExpr() != NULL) {
// If the expression is a compile-time constant, ensure that it
// is evaluated and canonicalized. See issue 27164.
- Instance& const_instance = Instance::ZoneHandle(Z);
- if (!GetCachedConstant(expr_pos, &const_instance)) {
- const_instance = EvaluateConstExpr(expr_pos, init_expr).raw();
- CacheConstantValue(expr_pos, const_instance);
- }
- init_expr = new(Z) LiteralNode(expr_pos, const_instance);
+ init_expr = FoldConstExpr(expr_pos, init_expr);
}
}
Field& field = Field::ZoneHandle(Z, cls.LookupInstanceField(field_name));
@@ -2812,12 +2807,7 @@ AstNode* Parser::ParseExternalInitializedField(const Field& field) {
} else {
init_expr = ParseExpr(kAllowConst, kConsumeCascades);
if (init_expr->EvalConstExpr() != NULL) {
- Instance& expr_value = Instance::ZoneHandle(Z);
- if (!GetCachedConstant(expr_pos, &expr_value)) {
- expr_value = EvaluateConstExpr(expr_pos, init_expr).raw();
- CacheConstantValue(expr_pos, expr_value);
- }
- init_expr = new(Z) LiteralNode(field.token_pos(), expr_value);
+ init_expr = FoldConstExpr(expr_pos, init_expr);
}
}
set_library(saved_library);
@@ -2860,12 +2850,7 @@ void Parser::ParseInitializedInstanceFields(const Class& cls,
TokenPosition expr_pos = TokenPos();
init_expr = ParseExpr(kAllowConst, kConsumeCascades);
if (init_expr->EvalConstExpr() != NULL) {
- Instance& expr_value = Instance::ZoneHandle(Z);
- if (!GetCachedConstant(expr_pos, &expr_value)) {
- expr_value = EvaluateConstExpr(expr_pos, init_expr).raw();
- CacheConstantValue(expr_pos, expr_value);
- }
- init_expr = new(Z) LiteralNode(field.token_pos(), expr_value);
+ init_expr = FoldConstExpr(expr_pos, init_expr);
}
}
}
@@ -11033,13 +11018,10 @@ AstNode* Parser::OptimizeBinaryOpNode(TokenPosition op_pos,
if (binary_op == Token::kIFNULL) {
// Handle a ?? b.
if ((lhs->EvalConstExpr() != NULL) && (rhs->EvalConstExpr() != NULL)) {
- Instance& expr_value = Instance::ZoneHandle(Z);
- if (!GetCachedConstant(op_pos, &expr_value)) {
- expr_value = EvaluateConstExpr(lhs->token_pos(), lhs).raw();
- if (expr_value.IsNull()) {
- expr_value = EvaluateConstExpr(rhs->token_pos(), rhs).raw();
- }
- CacheConstantValue(op_pos, expr_value);
+ Instance& expr_value = Instance::ZoneHandle(Z,
+ EvaluateConstExpr(lhs->token_pos(), lhs).raw());
+ if (expr_value.IsNull()) {
+ expr_value = EvaluateConstExpr(rhs->token_pos(), rhs).raw();
}
return new(Z) LiteralNode(op_pos, expr_value);
}
@@ -11117,8 +11099,7 @@ LiteralNode* Parser::FoldConstExpr(TokenPosition expr_pos, AstNode* expr) {
if (expr->EvalConstExpr() == NULL) {
ReportError(expr_pos, "expression is not a valid compile-time constant");
}
- return new(Z) LiteralNode(
- expr_pos, EvaluateConstExpr(expr_pos, expr));
+ return new(Z) LiteralNode(expr_pos, EvaluateConstExpr(expr_pos, expr));
}
@@ -11379,10 +11360,7 @@ AstNode* Parser::ParseExpr(bool require_compiletime_const,
return ParseCascades(expr);
}
if (require_compiletime_const) {
- const bool use_cache = !expr->IsLiteralNode();
- LiteralNode* const_value = FoldConstExpr(expr_pos, expr);
- if (use_cache) CacheConstantValue(expr_pos, const_value->literal());
- expr = const_value;
+ expr = FoldConstExpr(expr_pos, expr);
} else {
expr = LiteralIfStaticConst(Z, expr);
}
@@ -12477,6 +12455,7 @@ void Parser::CacheConstantValue(TokenPosition token_pos,
return;
}
InsertCachedConstantValue(script_, token_pos, value);
+ INC_STAT(thread_, num_cached_consts, 1);
}
@@ -14480,15 +14459,31 @@ const Instance& Parser::EvaluateConstExpr(TokenPosition expr_pos,
ASSERT(field.StaticValue() != Object::sentinel().raw());
ASSERT(field.StaticValue() != Object::transition_sentinel().raw());
return Instance::ZoneHandle(Z, field.StaticValue());
+ } else if (expr->IsTypeNode()) {
+ AbstractType& type =
+ AbstractType::ZoneHandle(Z, expr->AsTypeNode()->type().raw());
+ ASSERT(type.IsInstantiated() && !type.IsMalformedOrMalbounded());
+ return type;
+ } else if (expr->IsClosureNode()) {
+ const Function& func = expr->AsClosureNode()->function();
+ ASSERT((func.IsImplicitStaticClosureFunction()));
+ Instance& closure = Instance::ZoneHandle(Z, func.ImplicitStaticClosure());
+ closure = TryCanonicalize(closure, expr_pos);
+ return closure;
} else {
ASSERT(expr->EvalConstExpr() != NULL);
- ReturnNode* ret = new(Z) ReturnNode(expr->token_pos(), expr);
+ Instance& value = Instance::ZoneHandle(Z);
+ if (GetCachedConstant(expr_pos, &value)) {
+ return value;
+ }
+ ReturnNode* ret = new(Z) ReturnNode(expr_pos, expr);
// Compile time constant expressions cannot reference anything from a
// local scope.
LocalScope* empty_scope = new(Z) LocalScope(NULL, 0, 0);
- SequenceNode* seq = new(Z) SequenceNode(expr->token_pos(), empty_scope);
+ SequenceNode* seq = new(Z) SequenceNode(expr_pos, empty_scope);
seq->Add(ret);
+ INC_STAT(thread_, num_execute_const, 1);
Object& result = Object::Handle(Z, Compiler::ExecuteOnce(seq));
if (result.IsError()) {
ReportErrors(Error::Cast(result),
@@ -14496,9 +14491,9 @@ const Instance& Parser::EvaluateConstExpr(TokenPosition expr_pos,
"error evaluating constant expression");
}
ASSERT(result.IsInstance() || result.IsNull());
- Instance& value = Instance::ZoneHandle(Z);
value ^= result.raw();
- value = TryCanonicalize(value, TokenPos());
+ value = TryCanonicalize(value, expr_pos);
+ CacheConstantValue(expr_pos, value);
return value;
}
}
« no previous file with comments | « runtime/vm/compiler_stats.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698