| 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/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/code_descriptors.h" | 8 #include "vm/code_descriptors.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flags.h" | 10 #include "vm/flags.h" |
| (...skipping 1539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1550 node->function(), | 1550 node->function(), |
| 1551 node->arguments()->names(), | 1551 node->arguments()->names(), |
| 1552 values); | 1552 values); |
| 1553 ReturnComputation(call); | 1553 ReturnComputation(call); |
| 1554 } | 1554 } |
| 1555 | 1555 |
| 1556 | 1556 |
| 1557 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 1557 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 1558 // Context is saved around the call, it's treated as an extra operand | 1558 // Context is saved around the call, it's treated as an extra operand |
| 1559 // consumed by the call (but not an argument). | 1559 // consumed by the call (but not an argument). |
| 1560 AddInstruction(new BindInstr(temp_index(), new CurrentContextComp())); | 1560 BindInstr* context = new BindInstr(temp_index(), new CurrentContextComp()); |
| 1561 AddInstruction(context); |
| 1561 | 1562 |
| 1562 ArgumentGraphVisitor for_closure(owner(), temp_index() + 1); | 1563 ArgumentGraphVisitor for_closure(owner(), temp_index() + 1); |
| 1563 node->closure()->Visit(&for_closure); | 1564 node->closure()->Visit(&for_closure); |
| 1564 Append(for_closure); | 1565 Append(for_closure); |
| 1565 | 1566 |
| 1566 ZoneGrowableArray<Value*>* arguments = | 1567 ZoneGrowableArray<Value*>* arguments = |
| 1567 new ZoneGrowableArray<Value*>(node->arguments()->length()); | 1568 new ZoneGrowableArray<Value*>(node->arguments()->length()); |
| 1568 arguments->Add(for_closure.value()); | 1569 arguments->Add(for_closure.value()); |
| 1569 TranslateArgumentList(*node->arguments(), temp_index() + 2, arguments); | 1570 TranslateArgumentList(*node->arguments(), temp_index() + 2, arguments); |
| 1570 // First operand is the saved context, consumed by the call. | 1571 // First operand is the saved context, consumed by the call. |
| 1571 ClosureCallComp* call = new ClosureCallComp(node, | 1572 ClosureCallComp* call = new ClosureCallComp(node, |
| 1572 owner()->try_index(), | 1573 owner()->try_index(), |
| 1573 new TempVal(temp_index()), | 1574 new UseVal(context), |
| 1574 arguments); | 1575 arguments); |
| 1575 ReturnComputation(call); | 1576 ReturnComputation(call); |
| 1576 } | 1577 } |
| 1577 | 1578 |
| 1578 | 1579 |
| 1579 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 1580 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| 1580 AddInstruction(new BindInstr(temp_index(), new CurrentContextComp())); | 1581 BindInstr* context = new BindInstr(temp_index(), new CurrentContextComp()); |
| 1581 TempVal* ctx = new TempVal(temp_index()); | 1582 AddInstruction(context); |
| 1582 AddInstruction(new BindInstr(temp_index(), | 1583 BindInstr* clone = |
| 1583 new CloneContextComp(node->id(), | 1584 new BindInstr(temp_index(), |
| 1584 node->token_index(), | 1585 new CloneContextComp(node->id(), |
| 1585 owner()->try_index(), | 1586 node->token_index(), |
| 1586 ctx))); | 1587 owner()->try_index(), |
| 1587 TempVal* cloned_ctx = new TempVal(temp_index()); | 1588 new UseVal(context))); |
| 1588 ReturnComputation(new StoreContextComp(cloned_ctx)); | 1589 AddInstruction(clone); |
| 1590 ReturnComputation(new StoreContextComp(new UseVal(clone))); |
| 1589 } | 1591 } |
| 1590 | 1592 |
| 1591 | 1593 |
| 1592 TempVal* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node, | 1594 TempVal* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node, |
| 1593 int start_index) { | 1595 int start_index) { |
| 1594 const Class& cls = Class::ZoneHandle(node->constructor().owner()); | 1596 const Class& cls = Class::ZoneHandle(node->constructor().owner()); |
| 1595 const bool requires_type_arguments = cls.HasTypeArguments(); | 1597 const bool requires_type_arguments = cls.HasTypeArguments(); |
| 1596 | 1598 |
| 1597 ZoneGrowableArray<Value*>* allocate_arguments = | 1599 ZoneGrowableArray<Value*>* allocate_arguments = |
| 1598 new ZoneGrowableArray<Value*>(); | 1600 new ZoneGrowableArray<Value*>(); |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2017 } | 2019 } |
| 2018 | 2020 |
| 2019 | 2021 |
| 2020 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { | 2022 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { |
| 2021 return (node == owner()->parsed_function().node_sequence()) && | 2023 return (node == owner()->parsed_function().node_sequence()) && |
| 2022 (owner()->parsed_function().saved_context_var() != NULL); | 2024 (owner()->parsed_function().saved_context_var() != NULL); |
| 2023 } | 2025 } |
| 2024 | 2026 |
| 2025 | 2027 |
| 2026 void EffectGraphVisitor::UnchainContext() { | 2028 void EffectGraphVisitor::UnchainContext() { |
| 2027 AddInstruction(new BindInstr(temp_index(), new CurrentContextComp())); | 2029 BindInstr* context = new BindInstr(temp_index(), new CurrentContextComp()); |
| 2028 TempVal* temp_ctx = new TempVal(temp_index()); | 2030 AddInstruction(context); |
| 2029 NativeLoadFieldComp* load = new NativeLoadFieldComp( | 2031 BindInstr* parent = |
| 2030 temp_ctx, Context::parent_offset()); | 2032 new BindInstr(temp_index(), |
| 2031 AddInstruction(new BindInstr(temp_index(), load)); | 2033 new NativeLoadFieldComp( |
| 2032 TempVal* parent_ctx = new TempVal(temp_index()); | 2034 new UseVal(context), Context::parent_offset())); |
| 2033 AddInstruction(new DoInstr(new StoreContextComp(parent_ctx))); | 2035 AddInstruction(parent); |
| 2036 AddInstruction(new DoInstr(new StoreContextComp(new UseVal(parent)))); |
| 2034 } | 2037 } |
| 2035 | 2038 |
| 2036 | 2039 |
| 2037 // <Statement> ::= Sequence { scope: LocalScope | 2040 // <Statement> ::= Sequence { scope: LocalScope |
| 2038 // nodes: <Statement>* | 2041 // nodes: <Statement>* |
| 2039 // label: SourceLabel } | 2042 // label: SourceLabel } |
| 2040 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { | 2043 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { |
| 2041 LocalScope* scope = node->scope(); | 2044 LocalScope* scope = node->scope(); |
| 2042 const intptr_t num_context_variables = | 2045 const intptr_t num_context_variables = |
| 2043 (scope != NULL) ? scope->num_context_variables() : 0; | 2046 (scope != NULL) ? scope->num_context_variables() : 0; |
| 2044 int previous_context_level = owner()->context_level(); | 2047 int previous_context_level = owner()->context_level(); |
| 2045 if (num_context_variables > 0) { | 2048 if (num_context_variables > 0) { |
| 2046 // The loop local scope declares variables that are captured. | 2049 // The loop local scope declares variables that are captured. |
| 2047 // Allocate and chain a new context. | 2050 // Allocate and chain a new context. |
| 2048 // Allocate context computation (uses current CTX) | 2051 // Allocate context computation (uses current CTX) |
| 2049 AllocateContextComp* comp = new AllocateContextComp( | 2052 BindInstr* allocated_context = |
| 2050 node->token_index(), | 2053 new BindInstr(temp_index(), |
| 2051 owner()->try_index(), | 2054 new AllocateContextComp(node->token_index(), |
| 2052 num_context_variables); | 2055 owner()->try_index(), |
| 2053 AddInstruction(new BindInstr(temp_index(), comp)); | 2056 num_context_variables)); |
| 2054 Value* allocated_context_value = new TempVal(temp_index()); | 2057 AddInstruction(allocated_context); |
| 2055 | 2058 |
| 2056 // If this node_sequence is the body of the function being compiled, and if | 2059 // If this node_sequence is the body of the function being compiled, and if |
| 2057 // this function is not a closure, do not link the current context as the | 2060 // this function is not a closure, do not link the current context as the |
| 2058 // parent of the newly allocated context, as it is not accessible. Instead, | 2061 // parent of the newly allocated context, as it is not accessible. Instead, |
| 2059 // save it in a pre-allocated variable and restore it on exit. | 2062 // save it in a pre-allocated variable and restore it on exit. |
| 2060 if (MustSaveRestoreContext(node)) { | 2063 if (MustSaveRestoreContext(node)) { |
| 2061 AddInstruction(new BindInstr(temp_index() + 1, new CurrentContextComp())); | 2064 BindInstr* current_context = |
| 2065 new BindInstr(temp_index() + 1, new CurrentContextComp()); |
| 2066 AddInstruction(current_context); |
| 2062 StoreLocalComp* store_local = new StoreLocalComp( | 2067 StoreLocalComp* store_local = new StoreLocalComp( |
| 2063 *owner()->parsed_function().saved_context_var(), | 2068 *owner()->parsed_function().saved_context_var(), |
| 2064 new TempVal(temp_index() + 1), | 2069 new UseVal(current_context), |
| 2065 0); | 2070 0); |
| 2066 AddInstruction(new DoInstr(store_local)); | 2071 AddInstruction(new DoInstr(store_local)); |
| 2067 StoreContextComp* store_context = | 2072 StoreContextComp* store_context = |
| 2068 new StoreContextComp(new ConstantVal(Object::ZoneHandle())); | 2073 new StoreContextComp(new ConstantVal(Object::ZoneHandle())); |
| 2069 AddInstruction(new DoInstr(store_context)); | 2074 AddInstruction(new DoInstr(store_context)); |
| 2070 } | 2075 } |
| 2071 | 2076 |
| 2072 ChainContextComp* chain_context = new ChainContextComp( | 2077 ChainContextComp* chain_context = |
| 2073 allocated_context_value); | 2078 new ChainContextComp(new UseVal(allocated_context)); |
| 2074 AddInstruction(new DoInstr(chain_context)); | 2079 AddInstruction(new DoInstr(chain_context)); |
| 2075 owner()->set_context_level(scope->context_level()); | 2080 owner()->set_context_level(scope->context_level()); |
| 2076 | 2081 |
| 2077 // If this node_sequence is the body of the function being compiled, copy | 2082 // If this node_sequence is the body of the function being compiled, copy |
| 2078 // the captured parameters from the frame into the context. | 2083 // the captured parameters from the frame into the context. |
| 2079 if (node == owner()->parsed_function().node_sequence()) { | 2084 if (node == owner()->parsed_function().node_sequence()) { |
| 2080 ASSERT(scope->context_level() == 1); | 2085 ASSERT(scope->context_level() == 1); |
| 2081 const Function& function = owner()->parsed_function().function(); | 2086 const Function& function = owner()->parsed_function().function(); |
| 2082 const int num_params = function.NumberOfParameters(); | 2087 const int num_params = function.NumberOfParameters(); |
| 2083 int param_frame_index = | 2088 int param_frame_index = |
| 2084 (num_params == function.num_fixed_parameters()) ? 1 + num_params : -1; | 2089 (num_params == function.num_fixed_parameters()) ? 1 + num_params : -1; |
| 2085 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { | 2090 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { |
| 2086 const LocalVariable& parameter = *scope->VariableAt(pos); | 2091 const LocalVariable& parameter = *scope->VariableAt(pos); |
| 2087 ASSERT(parameter.owner() == scope); | 2092 ASSERT(parameter.owner() == scope); |
| 2088 if (parameter.is_captured()) { | 2093 if (parameter.is_captured()) { |
| 2089 // Create a temporary local describing the original position. | 2094 // Create a temporary local describing the original position. |
| 2090 const String& temp_name = String::ZoneHandle(String::Concat( | 2095 const String& temp_name = String::ZoneHandle(String::Concat( |
| 2091 parameter.name(), String::Handle(String::NewSymbol("-orig")))); | 2096 parameter.name(), String::Handle(String::NewSymbol("-orig")))); |
| 2092 LocalVariable* temp_local = new LocalVariable( | 2097 LocalVariable* temp_local = new LocalVariable( |
| 2093 0, // Token index. | 2098 0, // Token index. |
| 2094 temp_name, | 2099 temp_name, |
| 2095 Type::ZoneHandle(Type::DynamicType())); // Type. | 2100 Type::ZoneHandle(Type::DynamicType())); // Type. |
| 2096 temp_local->set_index(param_frame_index); | 2101 temp_local->set_index(param_frame_index); |
| 2097 | 2102 |
| 2098 // Copy parameter from local frame to current context. | 2103 // Copy parameter from local frame to current context. |
| 2099 LoadLocalComp* load_comp = new LoadLocalComp( | 2104 BindInstr* load = |
| 2100 *temp_local, owner()->context_level()); | 2105 new BindInstr(temp_index(), |
| 2101 AddInstruction(new BindInstr(temp_index(), load_comp)); | 2106 new LoadLocalComp(*temp_local, |
| 2107 owner()->context_level())); |
| 2108 AddInstruction(load); |
| 2102 StoreLocalComp* store_local = new StoreLocalComp( | 2109 StoreLocalComp* store_local = new StoreLocalComp( |
| 2103 parameter, | 2110 parameter, |
| 2104 new TempVal(temp_index()), | 2111 new UseVal(load), |
| 2105 owner()->context_level()); | 2112 owner()->context_level()); |
| 2106 AddInstruction(new DoInstr(store_local)); | 2113 AddInstruction(new DoInstr(store_local)); |
| 2107 // Write NULL to the source location to detect buggy accesses and | 2114 // Write NULL to the source location to detect buggy accesses and |
| 2108 // allow GC of passed value if it gets overwritten by a new value in | 2115 // allow GC of passed value if it gets overwritten by a new value in |
| 2109 // the function. | 2116 // the function. |
| 2110 StoreLocalComp* clear_local = new StoreLocalComp( | 2117 StoreLocalComp* clear_local = new StoreLocalComp( |
| 2111 *temp_local, | 2118 *temp_local, |
| 2112 new ConstantVal(Object::ZoneHandle()), | 2119 new ConstantVal(Object::ZoneHandle()), |
| 2113 owner()->context_level()); | 2120 owner()->context_level()); |
| 2114 AddInstruction(new DoInstr(clear_local)); | 2121 AddInstruction(new DoInstr(clear_local)); |
| 2115 } | 2122 } |
| 2116 } | 2123 } |
| 2117 } | 2124 } |
| 2118 } | 2125 } |
| 2119 | 2126 |
| 2120 if (FLAG_enable_type_checks && | 2127 if (FLAG_enable_type_checks && |
| 2121 (node == owner()->parsed_function().node_sequence())) { | 2128 (node == owner()->parsed_function().node_sequence())) { |
| 2122 const int num_params = | 2129 const int num_params = |
| 2123 owner()->parsed_function().function().NumberOfParameters(); | 2130 owner()->parsed_function().function().NumberOfParameters(); |
| 2124 for (int pos = 0; pos < num_params; pos++) { | 2131 for (int pos = 0; pos < num_params; pos++) { |
| 2125 const LocalVariable& parameter = *scope->VariableAt(pos); | 2132 const LocalVariable& parameter = *scope->VariableAt(pos); |
| 2126 ASSERT(parameter.owner() == scope); | 2133 ASSERT(parameter.owner() == scope); |
| 2127 if (!CanSkipTypeCheck(NULL, parameter.type())) { | 2134 if (!CanSkipTypeCheck(NULL, parameter.type())) { |
| 2128 LoadLocalComp* load = new LoadLocalComp(parameter, | 2135 BindInstr* load = |
| 2129 owner()->context_level()); | 2136 new BindInstr(temp_index(), |
| 2130 AddInstruction(new BindInstr(temp_index(), load)); | 2137 new LoadLocalComp(parameter, |
| 2131 TempVal* argument_value = new TempVal(temp_index()); | 2138 owner()->context_level())); |
| 2139 AddInstruction(load); |
| 2132 BuildAssertAssignable(node->ParameterIdAt(pos), | 2140 BuildAssertAssignable(node->ParameterIdAt(pos), |
| 2133 parameter.token_index(), | 2141 parameter.token_index(), |
| 2134 argument_value, | 2142 new UseVal(load), |
| 2135 parameter.type(), | 2143 parameter.type(), |
| 2136 parameter.name(), | 2144 parameter.name(), |
| 2137 temp_index()); | 2145 temp_index()); |
| 2138 } | 2146 } |
| 2139 } | 2147 } |
| 2140 } | 2148 } |
| 2141 | 2149 |
| 2142 intptr_t i = 0; | 2150 intptr_t i = 0; |
| 2143 while (is_open() && (i < node->length())) { | 2151 while (is_open() && (i < node->length())) { |
| 2144 EffectGraphVisitor for_effect(owner(), temp_index()); | 2152 EffectGraphVisitor for_effect(owner(), temp_index()); |
| (...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2844 char* chars = reinterpret_cast<char*>( | 2852 char* chars = reinterpret_cast<char*>( |
| 2845 Isolate::Current()->current_zone()->Allocate(len)); | 2853 Isolate::Current()->current_zone()->Allocate(len)); |
| 2846 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2854 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2847 const Error& error = Error::Handle( | 2855 const Error& error = Error::Handle( |
| 2848 LanguageError::New(String::Handle(String::New(chars)))); | 2856 LanguageError::New(String::Handle(String::New(chars)))); |
| 2849 Isolate::Current()->long_jump_base()->Jump(1, error); | 2857 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2850 } | 2858 } |
| 2851 | 2859 |
| 2852 | 2860 |
| 2853 } // namespace dart | 2861 } // namespace dart |
| OLD | NEW |