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

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

Issue 19370003: Enable allocation sinking for closures. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed comments Created 7 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
« no previous file with comments | « no previous file | 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/code_descriptors.h" 10 #include "vm/code_descriptors.h"
(...skipping 1822 matching lines...) Expand 10 before | Expand all | Expand 10 after
1833 1833
1834 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) { 1834 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) {
1835 Do(new PushTempInstr(value)); 1835 Do(new PushTempInstr(value));
1836 AllocateTempIndex(); 1836 AllocateTempIndex();
1837 1837
1838 ASSERT(value->definition()->temp_index() == temp_index() - 1); 1838 ASSERT(value->definition()->temp_index() == temp_index() - 1);
1839 intptr_t index = GetCurrentTempLocalIndex(); 1839 intptr_t index = GetCurrentTempLocalIndex();
1840 char name[64]; 1840 char name[64];
1841 OS::SNPrint(name, 64, ":tmp_local%"Pd, index); 1841 OS::SNPrint(name, 64, ":tmp_local%"Pd, index);
1842 LocalVariable* var = 1842 LocalVariable* var =
1843 new LocalVariable(0, String::ZoneHandle(Symbols::New(name)), 1843 new LocalVariable(0,
1844 Type::ZoneHandle(Type::DynamicType())); 1844 String::ZoneHandle(Symbols::New(name)),
1845 *value->Type()->ToAbstractType());
1845 var->set_index(index); 1846 var->set_index(index);
1846 return var; 1847 return var;
1847 } 1848 }
1848 1849
1849 1850
1850 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) { 1851 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) {
1851 Value* tmp = Bind(new LoadLocalInstr(*var)); 1852 Value* tmp = Bind(new LoadLocalInstr(*var));
1852 DeallocateTempIndex(1); 1853 DeallocateTempIndex(1);
1853 ASSERT(GetCurrentTempLocalIndex() == var->index()); 1854 ASSERT(GetCurrentTempLocalIndex() == var->index());
1854 return new DropTempsInstr(1, tmp); 1855 return new DropTempsInstr(1, tmp);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1971 closure ^= function.implicit_static_closure(); 1972 closure ^= function.implicit_static_closure();
1972 if (closure.IsNull()) { 1973 if (closure.IsNull()) {
1973 ObjectStore* object_store = Isolate::Current()->object_store(); 1974 ObjectStore* object_store = Isolate::Current()->object_store();
1974 const Context& context = Context::Handle(object_store->empty_context()); 1975 const Context& context = Context::Handle(object_store->empty_context());
1975 closure ^= Closure::New(function, context, Heap::kOld); 1976 closure ^= Closure::New(function, context, Heap::kOld);
1976 function.set_implicit_static_closure(closure); 1977 function.set_implicit_static_closure(closure);
1977 } 1978 }
1978 ReturnDefinition(new ConstantInstr(closure)); 1979 ReturnDefinition(new ConstantInstr(closure));
1979 return; 1980 return;
1980 } 1981 }
1981 Value* receiver = NULL;
1982 if (function.IsNonImplicitClosureFunction()) { 1982 if (function.IsNonImplicitClosureFunction()) {
1983 // The context scope may have already been set by the non-optimizing 1983 // The context scope may have already been set by the non-optimizing
1984 // compiler. If it was not, set it here. 1984 // compiler. If it was not, set it here.
1985 if (function.context_scope() == ContextScope::null()) { 1985 if (function.context_scope() == ContextScope::null()) {
1986 // TODO(regis): Why are we not doing this in the parser? 1986 // TODO(regis): Why are we not doing this in the parser?
1987 const ContextScope& context_scope = ContextScope::ZoneHandle( 1987 const ContextScope& context_scope = ContextScope::ZoneHandle(
1988 node->scope()->PreserveOuterScope(owner()->context_level())); 1988 node->scope()->PreserveOuterScope(owner()->context_level()));
1989 ASSERT(!function.HasCode()); 1989 ASSERT(!function.HasCode());
1990 ASSERT(function.context_scope() == ContextScope::null()); 1990 ASSERT(function.context_scope() == ContextScope::null());
1991 function.set_context_scope(context_scope); 1991 function.set_context_scope(context_scope);
1992 } 1992 }
1993 receiver = BuildNullValue(); 1993 ZoneGrowableArray<PushArgumentInstr*>* arguments =
1994 new ZoneGrowableArray<PushArgumentInstr*>(2);
1995 ASSERT(function.context_scope() != ContextScope::null());
1996
1997 // The function type of a closure may have type arguments. In that case,
1998 // pass the type arguments of the instantiator.
1999 const Class& cls = Class::ZoneHandle(function.signature_class());
2000 ASSERT(!cls.IsNull());
2001 const bool requires_type_arguments = cls.HasTypeArguments();
2002 Value* type_arguments = NULL;
2003 if (requires_type_arguments) {
2004 ASSERT(cls.type_arguments_field_offset() ==
2005 Closure::type_arguments_offset());
2006 const Class& instantiator_class = Class::Handle(
2007 owner()->parsed_function()->function().Owner());
2008 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(),
2009 instantiator_class,
2010 NULL);
2011 arguments->Add(PushArgument(type_arguments));
2012
2013 Value* instantiator_val = Bind(new ConstantInstr(
2014 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator))));
2015 arguments->Add(PushArgument(instantiator_val));
2016 }
2017 AllocateObjectInstr* alloc = new AllocateObjectInstr(node->token_pos(),
2018 cls,
2019 arguments);
2020 alloc->set_closure_function(function);
2021
2022 // Create fake fields for function and context. Only the context field is
2023 // stored at the allocation to be used later when inlining a closure call.
2024 const Field& function_field =
2025 Field::ZoneHandle(
2026 Field::New(Symbols::ClosureFunctionField(),
2027 false, // !static
2028 false, // !final
2029 false, // !const
2030 alloc->cls(),
2031 0)); // No token position.
2032 function_field.SetOffset(Closure::function_offset());
2033 const Field& context_field =
2034 Field::ZoneHandle(Field::New(
2035 Symbols::ClosureContextField(),
2036 false, // !static
2037 false, // !final
2038 false, // !const
2039 alloc->cls(),
2040 0)); // No token position.
2041 context_field.SetOffset(Closure::context_offset());
2042 alloc->set_context_field(context_field);
2043
2044 Value* closure_val = Bind(alloc);
2045 { LocalVariable* tmp_var = EnterTempLocalScope(closure_val);
2046 // Store function.
2047 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var));
2048 Value* func_val =
2049 Bind(new ConstantInstr(Function::ZoneHandle(function.raw())));
2050 Do(new StoreInstanceFieldInstr(function_field,
2051 tmp_val,
2052 func_val,
2053 kEmitStoreBarrier));
2054 // Store current context.
2055 tmp_val = Bind(new LoadLocalInstr(*tmp_var));
2056 Value* context = Bind(new CurrentContextInstr());
2057 Do(new StoreInstanceFieldInstr(context_field,
2058 tmp_val,
2059 context,
2060 kEmitStoreBarrier));
2061 ReturnDefinition(ExitTempLocalScope(tmp_var));
2062 }
1994 } else { 2063 } else {
1995 ASSERT(function.IsImplicitInstanceClosureFunction()); 2064 ASSERT(function.IsImplicitInstanceClosureFunction());
1996 ValueGraphVisitor for_receiver(owner(), temp_index()); 2065 ValueGraphVisitor for_receiver(owner(), temp_index());
1997 node->receiver()->Visit(&for_receiver); 2066 node->receiver()->Visit(&for_receiver);
1998 Append(for_receiver); 2067 Append(for_receiver);
1999 receiver = for_receiver.value(); 2068 Value* receiver = for_receiver.value();
2069
2070 PushArgumentInstr* push_receiver = PushArgument(receiver);
2071 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2072 new ZoneGrowableArray<PushArgumentInstr*>(2);
2073 arguments->Add(push_receiver);
2074 ASSERT(function.context_scope() != ContextScope::null());
2075
2076 // The function type of a closure may have type arguments. In that case,
2077 // pass the type arguments of the instantiator. Otherwise, pass null object.
2078 const Class& cls = Class::Handle(function.signature_class());
2079 ASSERT(!cls.IsNull());
2080 const bool requires_type_arguments = cls.HasTypeArguments();
2081 Value* type_arguments = NULL;
2082 if (requires_type_arguments) {
2083 const Class& instantiator_class = Class::Handle(
2084 owner()->parsed_function()->function().Owner());
2085 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(),
2086 instantiator_class,
2087 NULL);
2088 } else {
2089 type_arguments = BuildNullValue();
2090 }
2091 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments);
2092 arguments->Add(push_type_arguments);
2093 ReturnDefinition(
2094 new CreateClosureInstr(node->function(), arguments, node->token_pos()));
2000 } 2095 }
2001 PushArgumentInstr* push_receiver = PushArgument(receiver);
2002 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2003 new ZoneGrowableArray<PushArgumentInstr*>(2);
2004 arguments->Add(push_receiver);
2005 ASSERT(function.context_scope() != ContextScope::null());
2006
2007 // The function type of a closure may have type arguments. In that case, pass
2008 // the type arguments of the instantiator. Otherwise, pass null object.
2009 const Class& cls = Class::Handle(function.signature_class());
2010 ASSERT(!cls.IsNull());
2011 const bool requires_type_arguments = cls.HasTypeArguments();
2012 Value* type_arguments = NULL;
2013 if (requires_type_arguments) {
2014 ASSERT(!function.IsImplicitStaticClosureFunction());
2015 const Class& instantiator_class = Class::Handle(
2016 owner()->parsed_function()->function().Owner());
2017 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(),
2018 instantiator_class,
2019 NULL);
2020 } else {
2021 type_arguments = BuildNullValue();
2022 }
2023 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments);
2024 arguments->Add(push_type_arguments);
2025 ReturnDefinition(
2026 new CreateClosureInstr(node->function(), arguments, node->token_pos()));
2027 } 2096 }
2028 2097
2029 2098
2030 void EffectGraphVisitor::TranslateArgumentList( 2099 void EffectGraphVisitor::TranslateArgumentList(
2031 const ArgumentListNode& node, 2100 const ArgumentListNode& node,
2032 ZoneGrowableArray<Value*>* values) { 2101 ZoneGrowableArray<Value*>* values) {
2033 for (intptr_t i = 0; i < node.length(); ++i) { 2102 for (intptr_t i = 0; i < node.length(); ++i) {
2034 ValueGraphVisitor for_argument(owner(), temp_index()); 2103 ValueGraphVisitor for_argument(owner(), temp_index());
2035 node.NodeAt(i)->Visit(&for_argument); 2104 node.NodeAt(i)->Visit(&for_argument);
2036 Append(for_argument); 2105 Append(for_argument);
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
2193 // The uninstantiated type arguments cannot be verified to be within their 2262 // The uninstantiated type arguments cannot be verified to be within their
2194 // bounds at compile time, so verify them at runtime. 2263 // bounds at compile time, so verify them at runtime.
2195 allocation = new AllocateObjectWithBoundsCheckInstr(node); 2264 allocation = new AllocateObjectWithBoundsCheckInstr(node);
2196 } else { 2265 } else {
2197 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = 2266 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments =
2198 new ZoneGrowableArray<PushArgumentInstr*>(); 2267 new ZoneGrowableArray<PushArgumentInstr*>();
2199 if (requires_type_arguments) { 2268 if (requires_type_arguments) {
2200 BuildConstructorTypeArguments(node, allocate_arguments); 2269 BuildConstructorTypeArguments(node, allocate_arguments);
2201 } 2270 }
2202 2271
2203 allocation = new AllocateObjectInstr(node, allocate_arguments); 2272 allocation = new AllocateObjectInstr(
2273 node->token_pos(),
2274 Class::ZoneHandle(node->constructor().Owner()),
2275 allocate_arguments);
2204 } 2276 }
2205 return Bind(allocation); 2277 return Bind(allocation);
2206 } 2278 }
2207 2279
2208 2280
2209 void EffectGraphVisitor::BuildConstructorCall( 2281 void EffectGraphVisitor::BuildConstructorCall(
2210 ConstructorCallNode* node, 2282 ConstructorCallNode* node,
2211 PushArgumentInstr* push_alloc_value) { 2283 PushArgumentInstr* push_alloc_value) {
2212 Value* ctor_arg = Bind( 2284 Value* ctor_arg = Bind(
2213 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); 2285 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll))));
(...skipping 1336 matching lines...) Expand 10 before | Expand all | Expand 10 after
3550 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 3622 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
3551 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 3623 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
3552 OS::SNPrint(chars, len, kFormat, function_name, reason); 3624 OS::SNPrint(chars, len, kFormat, function_name, reason);
3553 const Error& error = Error::Handle( 3625 const Error& error = Error::Handle(
3554 LanguageError::New(String::Handle(String::New(chars)))); 3626 LanguageError::New(String::Handle(String::New(chars))));
3555 Isolate::Current()->long_jump_base()->Jump(1, error); 3627 Isolate::Current()->long_jump_base()->Jump(1, error);
3556 } 3628 }
3557 3629
3558 3630
3559 } // namespace dart 3631 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698