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

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

Issue 179443004: VM: Replace StoreVMField with StoreInstanceField. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 10 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
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/bit_vector.h" 9 #include "vm/bit_vector.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 return BuildStoreTemp(*owner()->parsed_function()->expression_temp_var(), 698 return BuildStoreTemp(*owner()->parsed_function()->expression_temp_var(),
699 value); 699 value);
700 } 700 }
701 701
702 702
703 Definition* EffectGraphVisitor::BuildLoadExprTemp() { 703 Definition* EffectGraphVisitor::BuildLoadExprTemp() {
704 return BuildLoadLocal(*owner()->parsed_function()->expression_temp_var()); 704 return BuildLoadLocal(*owner()->parsed_function()->expression_temp_var());
705 } 705 }
706 706
707 707
708 Definition* EffectGraphVisitor::BuildStoreLocal( 708 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local,
709 const LocalVariable& local, Value* value, bool result_is_needed) { 709 Value* value) {
710 if (local.is_captured()) { 710 if (local.is_captured()) {
711 if (result_is_needed) { 711 LocalVariable* tmp_var = EnterTempLocalScope(value);
712 value = Bind(BuildStoreExprTemp(value));
713 }
714
715 intptr_t delta = 712 intptr_t delta =
716 owner()->context_level() - local.owner()->context_level(); 713 owner()->context_level() - local.owner()->context_level();
717 ASSERT(delta >= 0); 714 ASSERT(delta >= 0);
718 Value* context = Bind(new CurrentContextInstr()); 715 Value* context = Bind(new CurrentContextInstr());
719 while (delta-- > 0) { 716 while (delta-- > 0) {
720 context = Bind(new LoadFieldInstr( 717 context = Bind(new LoadFieldInstr(
721 context, Context::parent_offset(), Type::ZoneHandle())); 718 context, Context::parent_offset(), Type::ZoneHandle()));
722 } 719 }
723 720 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var));
724 StoreVMFieldInstr* store = 721 StoreInstanceFieldInstr* store =
725 new StoreVMFieldInstr(context, 722 new StoreInstanceFieldInstr(Context::variable_offset(local.index()),
726 Context::variable_offset(local.index()), 723 context,
727 value, 724 tmp_val,
728 local.type()); 725 kEmitStoreBarrier);
729 if (result_is_needed) { 726 Do(store);
730 Do(store); 727 return ExitTempLocalScope(tmp_var);
731 return BuildLoadExprTemp();
732 } else {
733 return store;
734 }
735 } else { 728 } else {
736 return new StoreLocalInstr(local, value); 729 return new StoreLocalInstr(local, value);
737 } 730 }
738 } 731 }
739 732
740 733
741 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { 734 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) {
742 if (local.is_captured()) { 735 if (local.is_captured()) {
743 intptr_t delta = 736 intptr_t delta =
744 owner()->context_level() - local.owner()->context_level(); 737 owner()->context_level() - local.owner()->context_level();
745 ASSERT(delta >= 0); 738 ASSERT(delta >= 0);
746 Value* context = Bind(new CurrentContextInstr()); 739 Value* context = Bind(new CurrentContextInstr());
747 while (delta-- > 0) { 740 while (delta-- > 0) {
748 context = Bind(new LoadFieldInstr( 741 context = Bind(new LoadFieldInstr(
749 context, Context::parent_offset(), Type::ZoneHandle())); 742 context, Context::parent_offset(), Type::ZoneHandle()));
750 } 743 }
751 return new LoadFieldInstr(context, 744 return new LoadFieldInstr(context,
752 Context::variable_offset(local.index()), 745 Context::variable_offset(local.index()),
753 local.type()); 746 local.type());
754 } else { 747 } else {
755 return new LoadLocalInstr(local); 748 return new LoadLocalInstr(local);
756 } 749 }
757 } 750 }
758 751
759 752
760 // Stores current context into the 'variable' 753 // Stores current context into the 'variable'
761 void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable) { 754 void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable) {
762 Value* context = Bind(new CurrentContextInstr()); 755 Value* context = Bind(new CurrentContextInstr());
763 Do(BuildStoreLocal(variable, context, kResultNotNeeded)); 756 Do(BuildStoreLocal(variable, context));
764 } 757 }
765 758
766 759
767 // Loads context saved in 'context_variable' into the current context. 760 // Loads context saved in 'context_variable' into the current context.
768 void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable) { 761 void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable) {
769 Value* load_saved_context = Bind(BuildLoadLocal(variable)); 762 Value* load_saved_context = Bind(BuildLoadLocal(variable));
770 AddInstruction(new StoreContextInstr(load_saved_context)); 763 AddInstruction(new StoreContextInstr(load_saved_context));
771 } 764 }
772 765
773 766
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 // <Statement> ::= Return { value: <Expression> 939 // <Statement> ::= Return { value: <Expression>
947 // inlined_finally_list: <InlinedFinally>* } 940 // inlined_finally_list: <InlinedFinally>* }
948 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) { 941 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) {
949 ValueGraphVisitor for_value(owner()); 942 ValueGraphVisitor for_value(owner());
950 node->value()->Visit(&for_value); 943 node->value()->Visit(&for_value);
951 Append(for_value); 944 Append(for_value);
952 Value* return_value = for_value.value(); 945 Value* return_value = for_value.value();
953 946
954 if (node->inlined_finally_list_length() > 0) { 947 if (node->inlined_finally_list_length() > 0) {
955 LocalVariable* temp = node->saved_return_value_var(); 948 LocalVariable* temp = node->saved_return_value_var();
956 Do(BuildStoreLocal(*temp, return_value, kResultNotNeeded)); 949 Do(BuildStoreLocal(*temp, return_value));
957 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { 950 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
958 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)"); 951 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)");
959 EffectGraphVisitor for_effect(owner()); 952 EffectGraphVisitor for_effect(owner());
960 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); 953 node->InlinedFinallyNodeAt(i)->Visit(&for_effect);
961 Append(for_effect); 954 Append(for_effect);
962 if (!is_open()) { 955 if (!is_open()) {
963 return; 956 return;
964 } 957 }
965 } 958 }
966 return_value = Bind(BuildLoadLocal(*temp)); 959 return_value = Bind(BuildLoadLocal(*temp));
(...skipping 2123 matching lines...) Expand 10 before | Expand all | Expand 10 after
3090 3083
3091 3084
3092 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) { 3085 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
3093 Definition* load = BuildLoadLocal(node->local()); 3086 Definition* load = BuildLoadLocal(node->local());
3094 ReturnDefinition(load); 3087 ReturnDefinition(load);
3095 } 3088 }
3096 3089
3097 3090
3098 // <Expression> ::= StoreLocal { local: LocalVariable 3091 // <Expression> ::= StoreLocal { local: LocalVariable
3099 // value: <Expression> } 3092 // value: <Expression> }
3100 void EffectGraphVisitor::HandleStoreLocal(StoreLocalNode* node, 3093 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
3101 bool result_is_needed) {
3102 // If the right hand side is an expression that does not contain 3094 // If the right hand side is an expression that does not contain
3103 // a safe point for the debugger to stop, add an explicit stub 3095 // a safe point for the debugger to stop, add an explicit stub
3104 // call. 3096 // call.
3105 if (node->value()->IsLiteralNode() || 3097 if (node->value()->IsLiteralNode() ||
3106 node->value()->IsLoadLocalNode()) { 3098 node->value()->IsLoadLocalNode()) {
3107 AddInstruction(new DebugStepCheckInstr(node->token_pos(), 3099 AddInstruction(new DebugStepCheckInstr(node->token_pos(),
3108 PcDescriptors::kRuntimeCall)); 3100 PcDescriptors::kRuntimeCall));
3109 } 3101 }
3110 3102
3111 ValueGraphVisitor for_value(owner()); 3103 ValueGraphVisitor for_value(owner());
3112 node->value()->Visit(&for_value); 3104 node->value()->Visit(&for_value);
3113 Append(for_value); 3105 Append(for_value);
3114 Value* store_value = for_value.value(); 3106 Value* store_value = for_value.value();
3115 if (FLAG_enable_type_checks) { 3107 if (FLAG_enable_type_checks) {
3116 store_value = BuildAssignableValue(node->value()->token_pos(), 3108 store_value = BuildAssignableValue(node->value()->token_pos(),
3117 store_value, 3109 store_value,
3118 node->local().type(), 3110 node->local().type(),
3119 node->local().name()); 3111 node->local().name());
3120 } 3112 }
3121 Definition* store = BuildStoreLocal(node->local(), 3113 Definition* store = BuildStoreLocal(node->local(), store_value);
3122 store_value,
3123 result_is_needed);
3124 ReturnDefinition(store); 3114 ReturnDefinition(store);
3125 } 3115 }
3126 3116
3127 3117
3128 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
3129 HandleStoreLocal(node, kResultNotNeeded);
3130 }
3131
3132
3133 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
3134 HandleStoreLocal(node, kResultNeeded);
3135 }
3136
3137
3138 void EffectGraphVisitor::VisitLoadInstanceFieldNode( 3118 void EffectGraphVisitor::VisitLoadInstanceFieldNode(
3139 LoadInstanceFieldNode* node) { 3119 LoadInstanceFieldNode* node) {
3140 ValueGraphVisitor for_instance(owner()); 3120 ValueGraphVisitor for_instance(owner());
3141 node->instance()->Visit(&for_instance); 3121 node->instance()->Visit(&for_instance);
3142 Append(for_instance); 3122 Append(for_instance);
3143 LoadFieldInstr* load = new LoadFieldInstr( 3123 LoadFieldInstr* load = new LoadFieldInstr(
3144 for_instance.value(), 3124 for_instance.value(),
3145 node->field().Offset(), 3125 &node->field(),
3146 AbstractType::ZoneHandle(node->field().type())); 3126 AbstractType::ZoneHandle(node->field().type()));
3147 load->set_field(&node->field());
3148 if (owner()->exit_collector() != NULL) { 3127 if (owner()->exit_collector() != NULL) {
3149 // While inlining into an optimized function, the field has 3128 // While inlining into an optimized function, the field has
3150 // to be added to the list of guarded fields of the caller. 3129 // to be added to the list of guarded fields of the caller.
3151 if (node->field().guarded_cid() != kIllegalCid) { 3130 if (node->field().guarded_cid() != kIllegalCid) {
3152 if (!node->field().is_nullable() || 3131 if (!node->field().is_nullable() ||
3153 (node->field().guarded_cid() == kNullCid)) { 3132 (node->field().guarded_cid() == kNullCid)) {
3154 load->set_result_cid(node->field().guarded_cid()); 3133 load->set_result_cid(node->field().guarded_cid());
3155 } 3134 }
3156 FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field()); 3135 FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field());
3157 } 3136 }
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
3453 Value* allocated_context = 3432 Value* allocated_context =
3454 Bind(new AllocateContextInstr(node->token_pos(), 3433 Bind(new AllocateContextInstr(node->token_pos(),
3455 num_context_variables)); 3434 num_context_variables));
3456 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); 3435 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context);
3457 // If this node_sequence is the body of the function being compiled, and 3436 // If this node_sequence is the body of the function being compiled, and
3458 // if this function allocates context variables, but none of its enclosing 3437 // if this function allocates context variables, but none of its enclosing
3459 // functions do, the context on entry is not linked as parent of the 3438 // functions do, the context on entry is not linked as parent of the
3460 // allocated context but saved on entry and restored on exit as to prevent 3439 // allocated context but saved on entry and restored on exit as to prevent
3461 // memory leaks. 3440 // memory leaks.
3462 // In this case, the parser pre-allocates a variable to save the context. 3441 // In this case, the parser pre-allocates a variable to save the context.
3442 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var));
3463 Value* parent_context = NULL; 3443 Value* parent_context = NULL;
3464 if (MustSaveRestoreContext(node)) { 3444 if (MustSaveRestoreContext(node)) {
3465 BuildSaveContext( 3445 BuildSaveContext(
3466 *owner()->parsed_function()->saved_entry_context_var()); 3446 *owner()->parsed_function()->saved_entry_context_var());
3467 parent_context = Bind(new ConstantInstr(Object::ZoneHandle())); 3447 parent_context = Bind(new ConstantInstr(Object::ZoneHandle()));
3468 } else { 3448 } else {
3469 parent_context = Bind(new CurrentContextInstr()); 3449 parent_context = Bind(new CurrentContextInstr());
3470 } 3450 }
3471 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var)); 3451 Do(new StoreInstanceFieldInstr(Context::parent_offset(),
3472 Do(new StoreVMFieldInstr(tmp_val, 3452 tmp_val,
3473 Context::parent_offset(), 3453 parent_context,
3474 parent_context, 3454 kEmitStoreBarrier));
3475 Type::ZoneHandle()));
3476 AddInstruction( 3455 AddInstruction(
3477 new StoreContextInstr(Bind(ExitTempLocalScope(tmp_var)))); 3456 new StoreContextInstr(Bind(ExitTempLocalScope(tmp_var))));
3478 } 3457 }
3479 3458
3480 // If this node_sequence is the body of the function being compiled, copy 3459 // If this node_sequence is the body of the function being compiled, copy
3481 // the captured parameters from the frame into the context. 3460 // the captured parameters from the frame into the context.
3482 if (node == owner()->parsed_function()->node_sequence()) { 3461 if (node == owner()->parsed_function()->node_sequence()) {
3483 ASSERT(scope->context_level() == 1); 3462 ASSERT(scope->context_level() == 1);
3484 const Function& function = owner()->parsed_function()->function(); 3463 const Function& function = owner()->parsed_function()->function();
3485 const int num_params = function.NumParameters(); 3464 const int num_params = function.NumParameters();
3486 int param_frame_index = (num_params == function.num_fixed_parameters()) ? 3465 int param_frame_index = (num_params == function.num_fixed_parameters()) ?
3487 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; 3466 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp;
3488 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { 3467 for (int pos = 0; pos < num_params; param_frame_index--, pos++) {
3489 const LocalVariable& parameter = *scope->VariableAt(pos); 3468 const LocalVariable& parameter = *scope->VariableAt(pos);
3490 ASSERT(parameter.owner() == scope); 3469 ASSERT(parameter.owner() == scope);
3491 if (parameter.is_captured()) { 3470 if (parameter.is_captured()) {
3492 // Create a temporary local describing the original position. 3471 // Create a temporary local describing the original position.
3493 const String& temp_name = String::ZoneHandle(String::Concat( 3472 const String& temp_name = String::ZoneHandle(String::Concat(
3494 parameter.name(), String::Handle(Symbols::New("-orig")))); 3473 parameter.name(), String::Handle(Symbols::New("-orig"))));
3495 LocalVariable* temp_local = new LocalVariable( 3474 LocalVariable* temp_local = new LocalVariable(
3496 0, // Token index. 3475 0, // Token index.
3497 temp_name, 3476 temp_name,
3498 Type::ZoneHandle(Type::DynamicType())); // Type. 3477 Type::ZoneHandle(Type::DynamicType())); // Type.
3499 temp_local->set_index(param_frame_index); 3478 temp_local->set_index(param_frame_index);
3500 3479
3501 // Copy parameter from local frame to current context. 3480 // Copy parameter from local frame to current context.
3502 Value* load = Bind(BuildLoadLocal(*temp_local)); 3481 Value* load = Bind(BuildLoadLocal(*temp_local));
3503 Do(BuildStoreLocal(parameter, load, kResultNotNeeded)); 3482 Do(BuildStoreLocal(parameter, load));
3504 // Write NULL to the source location to detect buggy accesses and 3483 // Write NULL to the source location to detect buggy accesses and
3505 // allow GC of passed value if it gets overwritten by a new value in 3484 // allow GC of passed value if it gets overwritten by a new value in
3506 // the function. 3485 // the function.
3507 Value* null_constant = 3486 Value* null_constant =
3508 Bind(new ConstantInstr(Object::ZoneHandle())); 3487 Bind(new ConstantInstr(Object::ZoneHandle()));
3509 Do(BuildStoreLocal(*temp_local, null_constant, kResultNotNeeded)); 3488 Do(BuildStoreLocal(*temp_local, null_constant));
3510 } 3489 }
3511 } 3490 }
3512 } 3491 }
3513 } 3492 }
3514 3493
3515 if (FLAG_enable_type_checks && 3494 if (FLAG_enable_type_checks &&
3516 (node == owner()->parsed_function()->node_sequence())) { 3495 (node == owner()->parsed_function()->node_sequence())) {
3517 const Function& function = owner()->parsed_function()->function(); 3496 const Function& function = owner()->parsed_function()->function();
3518 const int num_params = function.NumParameters(); 3497 const int num_params = function.NumParameters();
3519 int pos = 0; 3498 int pos = 0;
(...skipping 15 matching lines...) Expand all
3535 Value* parameter_value = Bind(BuildLoadLocal(parameter)); 3514 Value* parameter_value = Bind(BuildLoadLocal(parameter));
3536 AssertAssignableInstr* assert_assignable = 3515 AssertAssignableInstr* assert_assignable =
3537 BuildAssertAssignable(parameter.token_pos(), 3516 BuildAssertAssignable(parameter.token_pos(),
3538 parameter_value, 3517 parameter_value,
3539 parameter.type(), 3518 parameter.type(),
3540 parameter.name()); 3519 parameter.name());
3541 parameter_value = Bind(assert_assignable); 3520 parameter_value = Bind(assert_assignable);
3542 // Store the type checked argument back to its corresponding local 3521 // Store the type checked argument back to its corresponding local
3543 // variable so that ssa renaming detects the dependency and makes use 3522 // variable so that ssa renaming detects the dependency and makes use
3544 // of the checked type in type propagation. 3523 // of the checked type in type propagation.
3545 Do(BuildStoreLocal(parameter, parameter_value, kResultNotNeeded)); 3524 Do(BuildStoreLocal(parameter, parameter_value));
3546 } 3525 }
3547 pos++; 3526 pos++;
3548 } 3527 }
3549 } 3528 }
3550 3529
3551 intptr_t i = 0; 3530 intptr_t i = 0;
3552 while (is_open() && (i < node->length())) { 3531 while (is_open() && (i < node->length())) {
3553 EffectGraphVisitor for_effect(owner()); 3532 EffectGraphVisitor for_effect(owner());
3554 node->NodeAt(i++)->Visit(&for_effect); 3533 node->NodeAt(i++)->Visit(&for_effect);
3555 Append(for_effect); 3534 Append(for_effect);
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
3942 LanguageError::kError, 3921 LanguageError::kError,
3943 Heap::kNew, 3922 Heap::kNew,
3944 "FlowGraphBuilder Bailout: %s %s", 3923 "FlowGraphBuilder Bailout: %s %s",
3945 String::Handle(function.name()).ToCString(), 3924 String::Handle(function.name()).ToCString(),
3946 reason)); 3925 reason));
3947 Isolate::Current()->long_jump_base()->Jump(1, error); 3926 Isolate::Current()->long_jump_base()->Jump(1, error);
3948 } 3927 }
3949 3928
3950 3929
3951 } // namespace dart 3930 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698