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

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 10832126: Store pointer instead of reference to LocalVariable in ast and flow graph. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/flow_graph_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "vm/ast_printer.h" 7 #include "vm/ast_printer.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/code_descriptors.h" 9 #include "vm/code_descriptors.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 } 199 }
200 200
201 201
202 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { 202 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) {
203 PushArgumentInstr* result = new PushArgumentInstr(value); 203 PushArgumentInstr* result = new PushArgumentInstr(value);
204 AddInstruction(result); 204 AddInstruction(result);
205 return result; 205 return result;
206 } 206 }
207 207
208 208
209 Computation* EffectGraphVisitor::BuildStoreLocal( 209 Computation* EffectGraphVisitor::BuildStoreLocal(const LocalVariable* local,
210 const LocalVariable& local, Value* value) { 210 Value* value) {
211 if (local.is_captured()) { 211 if (local->is_captured()) {
212 intptr_t delta = owner()->context_level() - 212 intptr_t delta = owner()->context_level() -
213 local.owner()->context_level(); 213 local->owner()->context_level();
214 ASSERT(delta >= 0); 214 ASSERT(delta >= 0);
215 Value* context = Bind(new CurrentContextComp()); 215 Value* context = Bind(new CurrentContextComp());
216 while (delta-- > 0) { 216 while (delta-- > 0) {
217 context = Bind(new LoadVMFieldComp( 217 context = Bind(new LoadVMFieldComp(
218 context, Context::parent_offset(), Type::ZoneHandle())); 218 context, Context::parent_offset(), Type::ZoneHandle()));
219 } 219 }
220 return new StoreVMFieldComp( 220 return new StoreVMFieldComp(
221 context, 221 context,
222 Context::variable_offset(local.index()), 222 Context::variable_offset(local->index()),
223 value, 223 value,
224 local.type()); 224 local->type());
225 } else { 225 } else {
226 return new StoreLocalComp(local, value, owner()->context_level()); 226 return new StoreLocalComp(local, value, owner()->context_level());
227 } 227 }
228 } 228 }
229 229
230 230
231 Computation* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { 231 Computation* EffectGraphVisitor::BuildLoadLocal(const LocalVariable* local) {
232 if (local.is_captured()) { 232 if (local->is_captured()) {
233 intptr_t delta = owner()->context_level() - 233 intptr_t delta = owner()->context_level() -
234 local.owner()->context_level(); 234 local->owner()->context_level();
235 ASSERT(delta >= 0); 235 ASSERT(delta >= 0);
236 Value* context = Bind(new CurrentContextComp()); 236 Value* context = Bind(new CurrentContextComp());
237 while (delta-- > 0) { 237 while (delta-- > 0) {
238 context = Bind(new LoadVMFieldComp( 238 context = Bind(new LoadVMFieldComp(
239 context, Context::parent_offset(), Type::ZoneHandle())); 239 context, Context::parent_offset(), Type::ZoneHandle()));
240 } 240 }
241 return new LoadVMFieldComp(context, 241 return new LoadVMFieldComp(context,
242 Context::variable_offset(local.index()), 242 Context::variable_offset(local->index()),
243 local.type()); 243 local->type());
244 } else { 244 } else {
245 return new LoadLocalComp(local, owner()->context_level()); 245 return new LoadLocalComp(local, owner()->context_level());
246 } 246 }
247 } 247 }
248 248
249 249
250 // Stores current context into the 'variable' 250 // Stores current context into the 'variable'
251 void EffectGraphVisitor::BuildStoreContext(const LocalVariable& variable) { 251 void EffectGraphVisitor::BuildStoreContext(const LocalVariable* variable) {
252 Value* context = Bind(new CurrentContextComp()); 252 Value* context = Bind(new CurrentContextComp());
253 Do(BuildStoreLocal(variable, context)); 253 Do(BuildStoreLocal(variable, context));
254 } 254 }
255 255
256 256
257 // Loads context saved in 'context_variable' into the current context. 257 // Loads context saved in 'context_variable' into the current context.
258 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) { 258 void EffectGraphVisitor::BuildLoadContext(const LocalVariable* variable) {
259 Value* load_saved_context = Bind(BuildLoadLocal(variable)); 259 Value* load_saved_context = Bind(BuildLoadLocal(variable));
260 Do(new StoreContextComp(load_saved_context)); 260 Do(new StoreContextComp(load_saved_context));
261 } 261 }
262 262
263 263
264 void TestGraphVisitor::ReturnValue(Value* value) { 264 void TestGraphVisitor::ReturnValue(Value* value) {
265 if (FLAG_enable_type_checks) { 265 if (FLAG_enable_type_checks) {
266 value = Bind(new AssertBooleanComp(condition_token_pos(), 266 value = Bind(new AssertBooleanComp(condition_token_pos(),
267 owner()->try_index(), 267 owner()->try_index(),
268 value)); 268 value));
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 return_value, 367 return_value,
368 dst_type, 368 dst_type,
369 dst_name); 369 dst_name);
370 } 370 }
371 } 371 }
372 372
373 intptr_t current_context_level = owner()->context_level(); 373 intptr_t current_context_level = owner()->context_level();
374 ASSERT(current_context_level >= 0); 374 ASSERT(current_context_level >= 0);
375 if (owner()->parsed_function().saved_context_var() != NULL) { 375 if (owner()->parsed_function().saved_context_var() != NULL) {
376 // CTX on entry was saved, but not linked as context parent. 376 // CTX on entry was saved, but not linked as context parent.
377 BuildLoadContext(*owner()->parsed_function().saved_context_var()); 377 BuildLoadContext(owner()->parsed_function().saved_context_var());
378 } else { 378 } else {
379 while (current_context_level-- > 0) { 379 while (current_context_level-- > 0) {
380 UnchainContext(); 380 UnchainContext();
381 } 381 }
382 } 382 }
383 383
384 AddInstruction(new ReturnInstr(node->token_pos(), return_value)); 384 AddInstruction(new ReturnInstr(node->token_pos(), return_value));
385 CloseFragment(); 385 CloseFragment();
386 } 386 }
387 387
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 for_right.Bind(new AssertBooleanComp(node->right()->token_pos(), 540 for_right.Bind(new AssertBooleanComp(node->right()->token_pos(),
541 owner()->try_index(), 541 owner()->try_index(),
542 right_value)); 542 right_value));
543 } 543 }
544 Value* constant_true = for_right.Bind(new ConstantVal(bool_true)); 544 Value* constant_true = for_right.Bind(new ConstantVal(bool_true));
545 Value* compare = 545 Value* compare =
546 for_right.Bind(new StrictCompareComp(Token::kEQ_STRICT, 546 for_right.Bind(new StrictCompareComp(Token::kEQ_STRICT,
547 right_value, 547 right_value,
548 constant_true)); 548 constant_true));
549 for_right.Do(BuildStoreLocal( 549 for_right.Do(BuildStoreLocal(
550 *owner()->parsed_function().expression_temp_var(), 550 owner()->parsed_function().expression_temp_var(),
551 compare)); 551 compare));
552 552
553 if (node->kind() == Token::kAND) { 553 if (node->kind() == Token::kAND) {
554 ValueGraphVisitor for_false(owner(), temp_index()); 554 ValueGraphVisitor for_false(owner(), temp_index());
555 Value* constant_false = for_false.Bind(new ConstantVal(bool_false)); 555 Value* constant_false = for_false.Bind(new ConstantVal(bool_false));
556 for_false.Do(BuildStoreLocal( 556 for_false.Do(BuildStoreLocal(
557 *owner()->parsed_function().expression_temp_var(), 557 owner()->parsed_function().expression_temp_var(),
558 constant_false)); 558 constant_false));
559 Join(for_test, for_right, for_false); 559 Join(for_test, for_right, for_false);
560 } else { 560 } else {
561 ASSERT(node->kind() == Token::kOR); 561 ASSERT(node->kind() == Token::kOR);
562 ValueGraphVisitor for_true(owner(), temp_index()); 562 ValueGraphVisitor for_true(owner(), temp_index());
563 Value* constant_true = for_true.Bind(new ConstantVal(bool_true)); 563 Value* constant_true = for_true.Bind(new ConstantVal(bool_true));
564 for_true.Do(BuildStoreLocal( 564 for_true.Do(BuildStoreLocal(
565 *owner()->parsed_function().expression_temp_var(), 565 owner()->parsed_function().expression_temp_var(),
566 constant_true)); 566 constant_true));
567 Join(for_test, for_true, for_right); 567 Join(for_test, for_true, for_right);
568 } 568 }
569 ReturnComputation( 569 ReturnComputation(
570 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); 570 BuildLoadLocal(owner()->parsed_function().expression_temp_var()));
571 return; 571 return;
572 } 572 }
573 EffectGraphVisitor::VisitBinaryOpNode(node); 573 EffectGraphVisitor::VisitBinaryOpNode(node);
574 } 574 }
575 575
576 576
577 void EffectGraphVisitor::BuildTypecheckArguments( 577 void EffectGraphVisitor::BuildTypecheckArguments(
578 intptr_t token_pos, 578 intptr_t token_pos,
579 Value** instantiator_result, 579 Value** instantiator_result,
580 Value** instantiator_type_arguments_result) { 580 Value** instantiator_type_arguments_result) {
581 Value* instantiator = NULL; 581 Value* instantiator = NULL;
582 Value* instantiator_type_arguments = NULL; 582 Value* instantiator_type_arguments = NULL;
583 const Class& instantiator_class = Class::Handle( 583 const Class& instantiator_class = Class::Handle(
584 owner()->parsed_function().function().owner()); 584 owner()->parsed_function().function().owner());
585 // Since called only when type tested against is not instantiated. 585 // Since called only when type tested against is not instantiated.
586 ASSERT(instantiator_class.NumTypeParameters() > 0); 586 ASSERT(instantiator_class.NumTypeParameters() > 0);
587 instantiator = BuildInstantiator(); 587 instantiator = BuildInstantiator();
588 if (instantiator == NULL) { 588 if (instantiator == NULL) {
589 // No instantiator when inside factory. 589 // No instantiator when inside factory.
590 instantiator = BuildNullValue(); 590 instantiator = BuildNullValue();
591 instantiator_type_arguments = 591 instantiator_type_arguments =
592 BuildInstantiatorTypeArguments(token_pos, NULL); 592 BuildInstantiatorTypeArguments(token_pos, NULL);
593 } else { 593 } else {
594 // Preserve instantiator. 594 // Preserve instantiator.
595 const LocalVariable& expr_temp = 595 const LocalVariable* expr_temp =
596 *owner()->parsed_function().expression_temp_var(); 596 owner()->parsed_function().expression_temp_var();
597 instantiator = Bind(BuildStoreLocal(expr_temp, instantiator)); 597 instantiator = Bind(BuildStoreLocal(expr_temp, instantiator));
598 Value* loaded = Bind(BuildLoadLocal(expr_temp)); 598 Value* loaded = Bind(BuildLoadLocal(expr_temp));
599 instantiator_type_arguments = 599 instantiator_type_arguments =
600 BuildInstantiatorTypeArguments(token_pos, loaded); 600 BuildInstantiatorTypeArguments(token_pos, loaded);
601 } 601 }
602 *instantiator_result = instantiator; 602 *instantiator_result = instantiator;
603 *instantiator_type_arguments_result = instantiator_type_arguments; 603 *instantiator_type_arguments_result = instantiator_type_arguments;
604 } 604 }
605 605
606 606
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { 880 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
881 TestGraphVisitor for_test(owner(), 881 TestGraphVisitor for_test(owner(),
882 temp_index(), 882 temp_index(),
883 node->condition()->token_pos()); 883 node->condition()->token_pos());
884 node->condition()->Visit(&for_test); 884 node->condition()->Visit(&for_test);
885 885
886 ValueGraphVisitor for_true(owner(), temp_index()); 886 ValueGraphVisitor for_true(owner(), temp_index());
887 node->true_expr()->Visit(&for_true); 887 node->true_expr()->Visit(&for_true);
888 ASSERT(for_true.is_open()); 888 ASSERT(for_true.is_open());
889 for_true.Do(BuildStoreLocal( 889 for_true.Do(BuildStoreLocal(
890 *owner()->parsed_function().expression_temp_var(), for_true.value())); 890 owner()->parsed_function().expression_temp_var(), for_true.value()));
891 891
892 ValueGraphVisitor for_false(owner(), temp_index()); 892 ValueGraphVisitor for_false(owner(), temp_index());
893 node->false_expr()->Visit(&for_false); 893 node->false_expr()->Visit(&for_false);
894 ASSERT(for_false.is_open()); 894 ASSERT(for_false.is_open());
895 for_false.Do(BuildStoreLocal( 895 for_false.Do(BuildStoreLocal(
896 *owner()->parsed_function().expression_temp_var(), for_false.value())); 896 owner()->parsed_function().expression_temp_var(), for_false.value()));
897 897
898 Join(for_test, for_true, for_false); 898 Join(for_test, for_true, for_false);
899 ReturnComputation( 899 ReturnComputation(
900 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); 900 BuildLoadLocal(owner()->parsed_function().expression_temp_var()));
901 } 901 }
902 902
903 903
904 // <Statement> ::= If { condition: <Expression> 904 // <Statement> ::= If { condition: <Expression>
905 // true_branch: <Sequence> 905 // true_branch: <Sequence>
906 // false_branch: <Sequence> } 906 // false_branch: <Sequence> }
907 void EffectGraphVisitor::VisitIfNode(IfNode* node) { 907 void EffectGraphVisitor::VisitIfNode(IfNode* node) {
908 TestGraphVisitor for_test(owner(), 908 TestGraphVisitor for_test(owner(),
909 temp_index(), 909 temp_index(),
910 node->condition()->token_pos()); 910 node->condition()->token_pos());
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
1405 node->closure()->Visit(&for_closure); 1405 node->closure()->Visit(&for_closure);
1406 Append(for_closure); 1406 Append(for_closure);
1407 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); 1407 PushArgumentInstr* push_closure = PushArgument(for_closure.value());
1408 1408
1409 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1409 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1410 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); 1410 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
1411 arguments->Add(push_closure); 1411 arguments->Add(push_closure);
1412 BuildPushArguments(*node->arguments(), arguments); 1412 BuildPushArguments(*node->arguments(), arguments);
1413 1413
1414 // Save context around the call. 1414 // Save context around the call.
1415 BuildStoreContext(*owner()->parsed_function().expression_temp_var()); 1415 BuildStoreContext(owner()->parsed_function().expression_temp_var());
1416 return new ClosureCallComp(node, owner()->try_index(), arguments); 1416 return new ClosureCallComp(node, owner()->try_index(), arguments);
1417 } 1417 }
1418 1418
1419 1419
1420 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 1420 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
1421 Do(BuildClosureCall(node)); 1421 Do(BuildClosureCall(node));
1422 // Restore context from saved location. 1422 // Restore context from saved location.
1423 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); 1423 BuildLoadContext(owner()->parsed_function().expression_temp_var());
1424 } 1424 }
1425 1425
1426 1426
1427 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { 1427 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
1428 Value* result = Bind(BuildClosureCall(node)); 1428 Value* result = Bind(BuildClosureCall(node));
1429 // Restore context from temp. 1429 // Restore context from temp.
1430 BuildLoadContext(*owner()->parsed_function().expression_temp_var()); 1430 BuildLoadContext(owner()->parsed_function().expression_temp_var());
1431 ReturnValue(result); 1431 ReturnValue(result);
1432 } 1432 }
1433 1433
1434 1434
1435 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { 1435 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
1436 Value* context = Bind(new CurrentContextComp()); 1436 Value* context = Bind(new CurrentContextComp());
1437 Value* clone = Bind(new CloneContextComp(node->token_pos(), 1437 Value* clone = Bind(new CloneContextComp(node->token_pos(),
1438 owner()->try_index(), 1438 owner()->try_index(),
1439 context)); 1439 context));
1440 ReturnComputation(new StoreContextComp(clone)); 1440 ReturnComputation(new StoreContextComp(clone));
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1637 } 1637 }
1638 // The type arguments are uninstantiated. The generated pseudo code: 1638 // The type arguments are uninstantiated. The generated pseudo code:
1639 // t1 = InstantiatorTypeArguments(); 1639 // t1 = InstantiatorTypeArguments();
1640 // t2 = ExtractConstructorTypeArguments(t1); 1640 // t2 = ExtractConstructorTypeArguments(t1);
1641 // t1 = ExtractConstructorInstantiator(t1); 1641 // t1 = ExtractConstructorInstantiator(t1);
1642 // t_n <- t2 1642 // t_n <- t2
1643 // t_n+1 <- t1 1643 // t_n+1 <- t1
1644 // Use expression_temp_var and node->allocated_object_var() locals to keep 1644 // Use expression_temp_var and node->allocated_object_var() locals to keep
1645 // intermediate results around (t1 and t2 above). 1645 // intermediate results around (t1 and t2 above).
1646 ASSERT(owner()->parsed_function().expression_temp_var() != NULL); 1646 ASSERT(owner()->parsed_function().expression_temp_var() != NULL);
1647 const LocalVariable& t1 = *owner()->parsed_function().expression_temp_var(); 1647 const LocalVariable* t1 = owner()->parsed_function().expression_temp_var();
1648 const LocalVariable& t2 = node->allocated_object_var(); 1648 const LocalVariable* t2 = node->allocated_object_var();
1649 Value* instantiator_type_arguments = BuildInstantiatorTypeArguments( 1649 Value* instantiator_type_arguments = BuildInstantiatorTypeArguments(
1650 node->token_pos(), NULL); 1650 node->token_pos(), NULL);
1651 ASSERT(instantiator_type_arguments->IsUse()); 1651 ASSERT(instantiator_type_arguments->IsUse());
1652 Value* stored_instantiator = 1652 Value* stored_instantiator =
1653 Bind(BuildStoreLocal(t1, instantiator_type_arguments)); 1653 Bind(BuildStoreLocal(t1, instantiator_type_arguments));
1654 // t1: instantiator type arguments. 1654 // t1: instantiator type arguments.
1655 1655
1656 Value* extract_type_arguments = Bind( 1656 Value* extract_type_arguments = Bind(
1657 new ExtractConstructorTypeArgumentsComp( 1657 new ExtractConstructorTypeArgumentsComp(
1658 node->token_pos(), 1658 node->token_pos(),
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1730 Append(for_receiver); 1730 Append(for_receiver);
1731 arguments->Add(PushArgument(for_receiver.value())); 1731 arguments->Add(PushArgument(for_receiver.value()));
1732 1732
1733 ValueGraphVisitor for_value(owner(), temp_index()); 1733 ValueGraphVisitor for_value(owner(), temp_index());
1734 node->value()->Visit(&for_value); 1734 node->value()->Visit(&for_value);
1735 Append(for_value); 1735 Append(for_value);
1736 1736
1737 Value* value = NULL; 1737 Value* value = NULL;
1738 if (result_is_needed) { 1738 if (result_is_needed) {
1739 value = Bind( 1739 value = Bind(
1740 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), 1740 BuildStoreLocal(owner()->parsed_function().expression_temp_var(),
1741 for_value.value())); 1741 for_value.value()));
1742 } else { 1742 } else {
1743 value = for_value.value(); 1743 value = for_value.value();
1744 } 1744 }
1745 arguments->Add(PushArgument(value)); 1745 arguments->Add(PushArgument(value));
1746 } 1746 }
1747 1747
1748 1748
1749 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 1749 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
1750 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1750 ZoneGrowableArray<PushArgumentInstr*>* arguments =
(...skipping 10 matching lines...) Expand all
1761 1761
1762 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { 1762 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
1763 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1763 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1764 new ZoneGrowableArray<PushArgumentInstr*>(2); 1764 new ZoneGrowableArray<PushArgumentInstr*>(2);
1765 BuildInstanceSetterArguments(node, arguments, true); // Value used. 1765 BuildInstanceSetterArguments(node, arguments, true); // Value used.
1766 Do(new InstanceSetterComp(node->token_pos(), 1766 Do(new InstanceSetterComp(node->token_pos(),
1767 owner()->try_index(), 1767 owner()->try_index(),
1768 node->field_name(), 1768 node->field_name(),
1769 arguments)); 1769 arguments));
1770 ReturnComputation( 1770 ReturnComputation(
1771 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); 1771 BuildLoadLocal(owner()->parsed_function().expression_temp_var()));
1772 } 1772 }
1773 1773
1774 1774
1775 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { 1775 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
1776 const String& getter_name = 1776 const String& getter_name =
1777 String::Handle(Field::GetterName(node->field_name())); 1777 String::Handle(Field::GetterName(node->field_name()));
1778 const Function& getter_function = 1778 const Function& getter_function =
1779 Function::ZoneHandle(node->cls().LookupStaticFunction(getter_name)); 1779 Function::ZoneHandle(node->cls().LookupStaticFunction(getter_name));
1780 ASSERT(!getter_function.IsNull()); 1780 ASSERT(!getter_function.IsNull());
1781 ZoneGrowableArray<PushArgumentInstr*>* arguments = 1781 ZoneGrowableArray<PushArgumentInstr*>* arguments =
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1839 // <Expression> ::= StoreLocal { local: LocalVariable 1839 // <Expression> ::= StoreLocal { local: LocalVariable
1840 // value: <Expression> } 1840 // value: <Expression> }
1841 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) { 1841 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
1842 ValueGraphVisitor for_value(owner(), temp_index()); 1842 ValueGraphVisitor for_value(owner(), temp_index());
1843 node->value()->Visit(&for_value); 1843 node->value()->Visit(&for_value);
1844 Append(for_value); 1844 Append(for_value);
1845 Value* store_value = for_value.value(); 1845 Value* store_value = for_value.value();
1846 if (FLAG_enable_type_checks) { 1846 if (FLAG_enable_type_checks) {
1847 store_value = BuildAssignableValue(node->value()->token_pos(), 1847 store_value = BuildAssignableValue(node->value()->token_pos(),
1848 store_value, 1848 store_value,
1849 node->local().type(), 1849 node->local()->type(),
1850 node->local().name()); 1850 node->local()->name());
1851 } 1851 }
1852 Computation* store = BuildStoreLocal(node->local(), store_value); 1852 Computation* store = BuildStoreLocal(node->local(), store_value);
1853 ReturnComputation(store); 1853 ReturnComputation(store);
1854 } 1854 }
1855 1855
1856 1856
1857 void EffectGraphVisitor::VisitLoadInstanceFieldNode( 1857 void EffectGraphVisitor::VisitLoadInstanceFieldNode(
1858 LoadInstanceFieldNode* node) { 1858 LoadInstanceFieldNode* node) {
1859 ValueGraphVisitor for_instance(owner(), temp_index()); 1859 ValueGraphVisitor for_instance(owner(), temp_index());
1860 node->instance()->Visit(&for_instance); 1860 node->instance()->Visit(&for_instance);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1963 index, 1963 index,
1964 value); 1964 value);
1965 ReturnComputation(store); 1965 ReturnComputation(store);
1966 } 1966 }
1967 1967
1968 1968
1969 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { 1969 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
1970 Value *array, *index, *value; 1970 Value *array, *index, *value;
1971 BuildStoreIndexedValues(node, &array, &index, &value); 1971 BuildStoreIndexedValues(node, &array, &index, &value);
1972 Value* saved_value = Bind( 1972 Value* saved_value = Bind(
1973 BuildStoreLocal(*owner()->parsed_function().expression_temp_var(), 1973 BuildStoreLocal(owner()->parsed_function().expression_temp_var(),
1974 value)); 1974 value));
1975 Do(new StoreIndexedComp(node->token_pos(), 1975 Do(new StoreIndexedComp(node->token_pos(),
1976 owner()->try_index(), 1976 owner()->try_index(),
1977 array, 1977 array,
1978 index, 1978 index,
1979 saved_value)); 1979 saved_value));
1980 ReturnComputation( 1980 ReturnComputation(
1981 BuildLoadLocal(*owner()->parsed_function().expression_temp_var())); 1981 BuildLoadLocal(owner()->parsed_function().expression_temp_var()));
1982 } 1982 }
1983 1983
1984 1984
1985 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { 1985 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const {
1986 return (node == owner()->parsed_function().node_sequence()) && 1986 return (node == owner()->parsed_function().node_sequence()) &&
1987 (owner()->parsed_function().saved_context_var() != NULL); 1987 (owner()->parsed_function().saved_context_var() != NULL);
1988 } 1988 }
1989 1989
1990 1990
1991 void EffectGraphVisitor::UnchainContext() { 1991 void EffectGraphVisitor::UnchainContext() {
(...skipping 22 matching lines...) Expand all
2014 Bind(new AllocateContextComp(node->token_pos(), 2014 Bind(new AllocateContextComp(node->token_pos(),
2015 owner()->try_index(), 2015 owner()->try_index(),
2016 num_context_variables)); 2016 num_context_variables));
2017 2017
2018 // If this node_sequence is the body of the function being compiled, and if 2018 // If this node_sequence is the body of the function being compiled, and if
2019 // this function is not a closure, do not link the current context as the 2019 // this function is not a closure, do not link the current context as the
2020 // parent of the newly allocated context, as it is not accessible. Instead, 2020 // parent of the newly allocated context, as it is not accessible. Instead,
2021 // save it in a pre-allocated variable and restore it on exit. 2021 // save it in a pre-allocated variable and restore it on exit.
2022 if (MustSaveRestoreContext(node)) { 2022 if (MustSaveRestoreContext(node)) {
2023 Value* current_context = Bind(new CurrentContextComp()); 2023 Value* current_context = Bind(new CurrentContextComp());
2024 Do(BuildStoreLocal(*owner()->parsed_function().saved_context_var(), 2024 Do(BuildStoreLocal(owner()->parsed_function().saved_context_var(),
2025 current_context)); 2025 current_context));
2026 Value* null_context = Bind(new ConstantVal(Object::ZoneHandle())); 2026 Value* null_context = Bind(new ConstantVal(Object::ZoneHandle()));
2027 Do(new StoreContextComp(null_context)); 2027 Do(new StoreContextComp(null_context));
2028 } 2028 }
2029 2029
2030 Do(new ChainContextComp(allocated_context)); 2030 Do(new ChainContextComp(allocated_context));
2031 owner()->set_context_level(scope->context_level()); 2031 owner()->set_context_level(scope->context_level());
2032 2032
2033 // If this node_sequence is the body of the function being compiled, copy 2033 // If this node_sequence is the body of the function being compiled, copy
2034 // the captured parameters from the frame into the context. 2034 // the captured parameters from the frame into the context.
2035 if (node == owner()->parsed_function().node_sequence()) { 2035 if (node == owner()->parsed_function().node_sequence()) {
2036 ASSERT(scope->context_level() == 1); 2036 ASSERT(scope->context_level() == 1);
2037 const Function& function = owner()->parsed_function().function(); 2037 const Function& function = owner()->parsed_function().function();
2038 const int num_params = function.NumberOfParameters(); 2038 const int num_params = function.NumberOfParameters();
2039 int param_frame_index = (num_params == function.num_fixed_parameters()) ? 2039 int param_frame_index = (num_params == function.num_fixed_parameters()) ?
2040 (1 + num_params) : ParsedFunction::kFirstLocalSlotIndex; 2040 (1 + num_params) : ParsedFunction::kFirstLocalSlotIndex;
2041 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { 2041 for (int pos = 0; pos < num_params; param_frame_index--, pos++) {
2042 const LocalVariable& parameter = *scope->VariableAt(pos); 2042 const LocalVariable* parameter = scope->VariableAt(pos);
2043 ASSERT(parameter.owner() == scope); 2043 ASSERT(parameter->owner() == scope);
2044 if (parameter.is_captured()) { 2044 if (parameter->is_captured()) {
2045 // Create a temporary local describing the original position. 2045 // Create a temporary local describing the original position.
2046 const String& temp_name = String::ZoneHandle(String::Concat( 2046 const String& temp_name = String::ZoneHandle(String::Concat(
2047 parameter.name(), String::Handle(Symbols::New("-orig")))); 2047 parameter->name(), String::Handle(Symbols::New("-orig"))));
2048 LocalVariable* temp_local = new LocalVariable( 2048 LocalVariable* temp_local = new LocalVariable(
2049 0, // Token index. 2049 0, // Token index.
2050 temp_name, 2050 temp_name,
2051 Type::ZoneHandle(Type::DynamicType())); // Type. 2051 Type::ZoneHandle(Type::DynamicType())); // Type.
2052 temp_local->set_index(param_frame_index); 2052 temp_local->set_index(param_frame_index);
2053 2053
2054 // Copy parameter from local frame to current context. 2054 // Copy parameter from local frame to current context.
2055 Value* load = Bind(BuildLoadLocal(*temp_local)); 2055 Value* load = Bind(BuildLoadLocal(temp_local));
2056 Do(BuildStoreLocal(parameter, load)); 2056 Do(BuildStoreLocal(parameter, load));
2057 // Write NULL to the source location to detect buggy accesses and 2057 // Write NULL to the source location to detect buggy accesses and
2058 // allow GC of passed value if it gets overwritten by a new value in 2058 // allow GC of passed value if it gets overwritten by a new value in
2059 // the function. 2059 // the function.
2060 Value* null_constant = Bind(new ConstantVal(Object::ZoneHandle())); 2060 Value* null_constant = Bind(new ConstantVal(Object::ZoneHandle()));
2061 Do(BuildStoreLocal(*temp_local, null_constant)); 2061 Do(BuildStoreLocal(temp_local, null_constant));
2062 } 2062 }
2063 } 2063 }
2064 } 2064 }
2065 } 2065 }
2066 2066
2067 if (FLAG_enable_type_checks && 2067 if (FLAG_enable_type_checks &&
2068 (node == owner()->parsed_function().node_sequence())) { 2068 (node == owner()->parsed_function().node_sequence())) {
2069 const Function& function = owner()->parsed_function().function(); 2069 const Function& function = owner()->parsed_function().function();
2070 const int num_params = function.NumberOfParameters(); 2070 const int num_params = function.NumberOfParameters();
2071 int pos = 0; 2071 int pos = 0;
2072 if (function.IsConstructor()) { 2072 if (function.IsConstructor()) {
2073 // Skip type checking of receiver and phase for constructor functions. 2073 // Skip type checking of receiver and phase for constructor functions.
2074 pos = 2; 2074 pos = 2;
2075 } else if (function.IsFactory() || function.IsDynamicFunction()) { 2075 } else if (function.IsFactory() || function.IsDynamicFunction()) {
2076 // Skip type checking of type arguments for factory functions. 2076 // Skip type checking of type arguments for factory functions.
2077 // Skip type checking of receiver for instance functions. 2077 // Skip type checking of receiver for instance functions.
2078 pos = 1; 2078 pos = 1;
2079 } 2079 }
2080 while (pos < num_params) { 2080 while (pos < num_params) {
2081 const LocalVariable& parameter = *scope->VariableAt(pos); 2081 const LocalVariable* parameter = scope->VariableAt(pos);
2082 ASSERT(parameter.owner() == scope); 2082 ASSERT(parameter->owner() == scope);
2083 if (!CanSkipTypeCheck(parameter.token_pos(), 2083 if (!CanSkipTypeCheck(parameter->token_pos(),
2084 NULL, 2084 NULL,
2085 parameter.type(), 2085 parameter->type(),
2086 parameter.name())) { 2086 parameter->name())) {
2087 Value* load = Bind(BuildLoadLocal(parameter)); 2087 Value* load = Bind(BuildLoadLocal(parameter));
2088 Do(BuildAssertAssignable(parameter.token_pos(), 2088 Do(BuildAssertAssignable(parameter->token_pos(),
2089 load, 2089 load,
2090 parameter.type(), 2090 parameter->type(),
2091 parameter.name())); 2091 parameter->name()));
2092 } 2092 }
2093 pos++; 2093 pos++;
2094 } 2094 }
2095 } 2095 }
2096 2096
2097 intptr_t i = 0; 2097 intptr_t i = 0;
2098 while (is_open() && (i < node->length())) { 2098 while (is_open() && (i < node->length())) {
2099 EffectGraphVisitor for_effect(owner(), temp_index()); 2099 EffectGraphVisitor for_effect(owner(), temp_index());
2100 node->NodeAt(i++)->Visit(&for_effect); 2100 node->NodeAt(i++)->Visit(&for_effect);
2101 Append(for_effect); 2101 Append(for_effect);
2102 if (!is_open()) { 2102 if (!is_open()) {
2103 // E.g., because of a JumpNode. 2103 // E.g., because of a JumpNode.
2104 break; 2104 break;
2105 } 2105 }
2106 } 2106 }
2107 2107
2108 if (is_open()) { 2108 if (is_open()) {
2109 if (MustSaveRestoreContext(node)) { 2109 if (MustSaveRestoreContext(node)) {
2110 ASSERT(num_context_variables > 0); 2110 ASSERT(num_context_variables > 0);
2111 BuildLoadContext(*owner()->parsed_function().saved_context_var()); 2111 BuildLoadContext(owner()->parsed_function().saved_context_var());
2112 } else if (num_context_variables > 0) { 2112 } else if (num_context_variables > 0) {
2113 UnchainContext(); 2113 UnchainContext();
2114 } 2114 }
2115 } 2115 }
2116 2116
2117 // No continue on sequence allowed. 2117 // No continue on sequence allowed.
2118 ASSERT((node->label() == NULL) || 2118 ASSERT((node->label() == NULL) ||
2119 (node->label()->join_for_continue() == NULL)); 2119 (node->label()->join_for_continue() == NULL));
2120 // If this node sequence is labeled, a break out of the sequence will have 2120 // If this node sequence is labeled, a break out of the sequence will have
2121 // taken care of unchaining the context. 2121 // taken care of unchaining the context.
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
2583 for (intptr_t i = 0; i < current->InputCount(); ++i) { 2583 for (intptr_t i = 0; i < current->InputCount(); ++i) {
2584 Value* v = current->InputAt(i); 2584 Value* v = current->InputAt(i);
2585 if (!v->IsUse()) continue; 2585 if (!v->IsUse()) continue;
2586 // Update expression stack. 2586 // Update expression stack.
2587 ASSERT(env->length() > var_count); 2587 ASSERT(env->length() > var_count);
2588 env->RemoveLast(); 2588 env->RemoveLast();
2589 BindInstr* as_bind = v->AsUse()->definition()->AsBind(); 2589 BindInstr* as_bind = v->AsUse()->definition()->AsBind();
2590 if ((as_bind != NULL) && as_bind->computation()->IsLoadLocal()) { 2590 if ((as_bind != NULL) && as_bind->computation()->IsLoadLocal()) {
2591 Computation* comp = as_bind->computation(); 2591 Computation* comp = as_bind->computation();
2592 intptr_t index = 2592 intptr_t index =
2593 comp->AsLoadLocal()->local().BitIndexIn(fixed_parameter_count); 2593 comp->AsLoadLocal()->local()->BitIndexIn(fixed_parameter_count);
2594 current->SetInputAt(i, CopyValue((*env)[index])); 2594 current->SetInputAt(i, CopyValue((*env)[index]));
2595 } 2595 }
2596 if ((as_bind != NULL) && as_bind->computation()->IsStoreLocal()) { 2596 if ((as_bind != NULL) && as_bind->computation()->IsStoreLocal()) {
2597 // For each use of a StoreLocal: Replace it with the value from the 2597 // For each use of a StoreLocal: Replace it with the value from the
2598 // environment. 2598 // environment.
2599 Computation* comp = as_bind->computation(); 2599 Computation* comp = as_bind->computation();
2600 intptr_t index = 2600 intptr_t index =
2601 comp->AsStoreLocal()->local().BitIndexIn(fixed_parameter_count); 2601 comp->AsStoreLocal()->local()->BitIndexIn(fixed_parameter_count);
2602 current->SetInputAt(i, CopyValue((*env)[index])); 2602 current->SetInputAt(i, CopyValue((*env)[index]));
2603 } 2603 }
2604 } 2604 }
2605 2605
2606 // Drop pushed arguments for calls. 2606 // Drop pushed arguments for calls.
2607 for (intptr_t j = 0; j < current->ArgumentCount(); j++) { 2607 for (intptr_t j = 0; j < current->ArgumentCount(); j++) {
2608 env->RemoveLast(); 2608 env->RemoveLast();
2609 } 2609 }
2610 2610
2611 // 2b. Handle LoadLocal and StoreLocal. 2611 // 2b. Handle LoadLocal and StoreLocal.
2612 // For each LoadLocal: Remove it from the graph. 2612 // For each LoadLocal: Remove it from the graph.
2613 // For each StoreLocal: Remove it from the graph and update the environment. 2613 // For each StoreLocal: Remove it from the graph and update the environment.
2614 BindInstr* bind = current->AsBind(); 2614 BindInstr* bind = current->AsBind();
2615 if (bind != NULL) { 2615 if (bind != NULL) {
2616 LoadLocalComp* load = bind->computation()->AsLoadLocal(); 2616 LoadLocalComp* load = bind->computation()->AsLoadLocal();
2617 StoreLocalComp* store = bind->computation()->AsStoreLocal(); 2617 StoreLocalComp* store = bind->computation()->AsStoreLocal();
2618 if ((load != NULL) || (store != NULL)) { 2618 if ((load != NULL) || (store != NULL)) {
2619 intptr_t index; 2619 intptr_t index;
2620 if (store != NULL) { 2620 if (store != NULL) {
2621 index = store->local().BitIndexIn(fixed_parameter_count); 2621 index = store->local()->BitIndexIn(fixed_parameter_count);
2622 // Update renaming environment. 2622 // Update renaming environment.
2623 (*env)[index] = store->value(); 2623 (*env)[index] = store->value();
2624 } else { 2624 } else {
2625 // The graph construction ensures we do not have an unused LoadLocal 2625 // The graph construction ensures we do not have an unused LoadLocal
2626 // computation. 2626 // computation.
2627 ASSERT(bind->is_used()); 2627 ASSERT(bind->is_used());
2628 index = load->local().BitIndexIn(fixed_parameter_count); 2628 index = load->local()->BitIndexIn(fixed_parameter_count);
2629 } 2629 }
2630 // Update expression stack and remove from graph. 2630 // Update expression stack and remove from graph.
2631 if (bind->is_used()) { 2631 if (bind->is_used()) {
2632 env->Add(CopyValue((*env)[index])); 2632 env->Add(CopyValue((*env)[index]));
2633 } 2633 }
2634 it.RemoveCurrentFromGraph(); 2634 it.RemoveCurrentFromGraph();
2635 } else { 2635 } else {
2636 // Not a load or store. 2636 // Not a load or store.
2637 if (bind->is_used()) { 2637 if (bind->is_used()) {
2638 // Assign fresh SSA temporary and update expression stack. 2638 // Assign fresh SSA temporary and update expression stack.
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2688 char* chars = reinterpret_cast<char*>( 2688 char* chars = reinterpret_cast<char*>(
2689 Isolate::Current()->current_zone()->Allocate(len)); 2689 Isolate::Current()->current_zone()->Allocate(len));
2690 OS::SNPrint(chars, len, kFormat, function_name, reason); 2690 OS::SNPrint(chars, len, kFormat, function_name, reason);
2691 const Error& error = Error::Handle( 2691 const Error& error = Error::Handle(
2692 LanguageError::New(String::Handle(String::New(chars)))); 2692 LanguageError::New(String::Handle(String::New(chars))));
2693 Isolate::Current()->long_jump_base()->Jump(1, error); 2693 Isolate::Current()->long_jump_base()->Jump(1, error);
2694 } 2694 }
2695 2695
2696 2696
2697 } // namespace dart 2697 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698