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

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

Issue 178233003: Allocate instance closures similarly to regular closures, i.e. without a (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 | « no previous file | no next file » | 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 2303 matching lines...) Expand 10 before | Expand all | Expand 10 after
2314 // Store current context. 2314 // Store current context.
2315 tmp_val = Bind(new LoadLocalInstr(*tmp_var)); 2315 tmp_val = Bind(new LoadLocalInstr(*tmp_var));
2316 Value* context = Bind(new CurrentContextInstr()); 2316 Value* context = Bind(new CurrentContextInstr());
2317 Do(new StoreInstanceFieldInstr(context_field, 2317 Do(new StoreInstanceFieldInstr(context_field,
2318 tmp_val, 2318 tmp_val,
2319 context, 2319 context,
2320 kEmitStoreBarrier)); 2320 kEmitStoreBarrier));
2321 ReturnDefinition(ExitTempLocalScope(tmp_var)); 2321 ReturnDefinition(ExitTempLocalScope(tmp_var));
2322 } 2322 }
2323 } else { 2323 } else {
2324 // TODO(regis): Merge this branch in the above one.
2324 ASSERT(function.IsImplicitInstanceClosureFunction()); 2325 ASSERT(function.IsImplicitInstanceClosureFunction());
2325 ValueGraphVisitor for_receiver(owner());
2326 node->receiver()->Visit(&for_receiver);
2327 Append(for_receiver);
2328 Value* receiver = for_receiver.value();
2329 2326
2330 PushArgumentInstr* push_receiver = PushArgument(receiver);
2331 ZoneGrowableArray<PushArgumentInstr*>* arguments = 2327 ZoneGrowableArray<PushArgumentInstr*>* arguments =
2332 new ZoneGrowableArray<PushArgumentInstr*>(2); 2328 new ZoneGrowableArray<PushArgumentInstr*>(2); // 1? here and above too?
2333 arguments->Add(push_receiver);
2334 ASSERT(function.context_scope() != ContextScope::null()); 2329 ASSERT(function.context_scope() != ContextScope::null());
2335 2330
2336 // The function type of a closure may have type arguments. In that case, 2331 // The function type of a closure may have type arguments. In that case,
2337 // pass the type arguments of the instantiator. Otherwise, pass null object. 2332 // pass the type arguments of the instantiator. Otherwise, pass null object.
2338 const Class& cls = Class::Handle(function.signature_class()); 2333 const Class& cls = Class::ZoneHandle(function.signature_class());
2339 ASSERT(!cls.IsNull()); 2334 ASSERT(!cls.IsNull());
2340 const bool requires_type_arguments = cls.NumTypeArguments() > 0; 2335 const bool requires_type_arguments = cls.NumTypeArguments() > 0;
2341 Value* type_arguments = NULL; 2336 Value* type_arguments = NULL;
2342 if (requires_type_arguments) { 2337 if (requires_type_arguments) {
2343 const Class& instantiator_class = Class::Handle( 2338 const Class& instantiator_class = Class::Handle(
2344 owner()->parsed_function()->function().Owner()); 2339 owner()->parsed_function()->function().Owner());
2345 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), 2340 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(),
2346 instantiator_class, 2341 instantiator_class,
2347 NULL); 2342 NULL);
2348 } else { 2343 arguments->Add(PushArgument(type_arguments));
2349 type_arguments = BuildNullValue();
2350 } 2344 }
2351 PushArgumentInstr* push_type_arguments = PushArgument(type_arguments); 2345 AllocateObjectInstr* alloc = new AllocateObjectInstr(node->token_pos(),
2352 arguments->Add(push_type_arguments); 2346 cls,
2353 ReturnDefinition( 2347 arguments);
2354 new CreateClosureInstr(node->function(), arguments, node->token_pos())); 2348 alloc->set_closure_function(function);
2349
2350 // Create fake fields for function and context. Only the context field is
2351 // stored at the allocation to be used later when inlining a closure call.
2352 const Field& function_field =
2353 Field::ZoneHandle(
2354 Field::New(Symbols::ClosureFunctionField(),
2355 false, // !static
2356 false, // !final
2357 false, // !const
2358 alloc->cls(),
2359 0)); // No token position.
2360 function_field.SetOffset(Closure::function_offset());
2361 const Field& context_field =
2362 Field::ZoneHandle(Field::New(
2363 Symbols::ClosureContextField(),
2364 false, // !static
2365 false, // !final
2366 false, // !const
2367 alloc->cls(),
2368 0)); // No token position.
2369 context_field.SetOffset(Closure::context_offset());
2370 alloc->set_context_field(context_field);
2371
2372 Value* closure_val = Bind(alloc);
2373 { LocalVariable* tmp_var = EnterTempLocalScope(closure_val);
2374 // Store function.
2375 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var));
2376 Value* func_val =
2377 Bind(new ConstantInstr(Function::ZoneHandle(function.raw())));
2378 Do(new StoreInstanceFieldInstr(function_field,
2379 tmp_val,
2380 func_val,
2381 kEmitStoreBarrier));
2382 // Create new context containing the receiver.
2383 const intptr_t kNumContextVariables = 1; // The receiver.
2384 Value* allocated_context =
2385 Bind(new AllocateContextInstr(node->token_pos(),
2386 kNumContextVariables));
2387 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context);
2388 ValueGraphVisitor for_receiver(owner());
2389 node->receiver()->Visit(&for_receiver);
Florian Schneider 2014/02/24 18:50:23 Is there a dependency on the evaluation order of t
regis 2014/02/24 19:01:30 I do not think that the evaluation of the type arg
2390 Append(for_receiver);
2391 Value* receiver = for_receiver.value();
2392 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var));
2393 Do(new StoreVMFieldInstr(tmp_val,
2394 Context::variable_offset(0),
2395 receiver,
2396 Type::ZoneHandle()));
2397 AddInstruction(
2398 new StoreContextInstr(Bind(ExitTempLocalScope(tmp_var))));
Florian Schneider 2014/02/24 18:50:23 The StoreContext does not appear in the original c
regis 2014/02/24 19:01:30 No idea why I have this StoreContextInstr here.
2399 }
2400 // Store new context.
2401 tmp_val = Bind(new LoadLocalInstr(*tmp_var));
2402 Do(new StoreInstanceFieldInstr(context_field,
Florian Schneider 2014/02/24 18:50:23 Try move this store into the inner TempLocalScope:
regis 2014/02/24 19:01:30 Yes, exactly. I already renamed these as you sugge
2403 tmp_val,
2404 allocated_context,
2405 kEmitStoreBarrier));
2406 ReturnDefinition(ExitTempLocalScope(tmp_var));
2407 }
2355 } 2408 }
2356 } 2409 }
2357 2410
2358 2411
2359 void EffectGraphVisitor::BuildPushArguments( 2412 void EffectGraphVisitor::BuildPushArguments(
2360 const ArgumentListNode& node, 2413 const ArgumentListNode& node,
2361 ZoneGrowableArray<PushArgumentInstr*>* values) { 2414 ZoneGrowableArray<PushArgumentInstr*>* values) {
2362 for (intptr_t i = 0; i < node.length(); ++i) { 2415 for (intptr_t i = 0; i < node.length(); ++i) {
2363 ValueGraphVisitor for_argument(owner()); 2416 ValueGraphVisitor for_argument(owner());
2364 node.NodeAt(i)->Visit(&for_argument); 2417 node.NodeAt(i)->Visit(&for_argument);
(...skipping 1576 matching lines...) Expand 10 before | Expand all | Expand 10 after
3941 LanguageError::kError, 3994 LanguageError::kError,
3942 Heap::kNew, 3995 Heap::kNew,
3943 "FlowGraphBuilder Bailout: %s %s", 3996 "FlowGraphBuilder Bailout: %s %s",
3944 String::Handle(function.name()).ToCString(), 3997 String::Handle(function.name()).ToCString(),
3945 reason)); 3998 reason));
3946 Isolate::Current()->long_jump_base()->Jump(1, error); 3999 Isolate::Current()->long_jump_base()->Jump(1, error);
3947 } 4000 }
3948 4001
3949 4002
3950 } // namespace dart 4003 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698