 Chromium Code Reviews
 Chromium Code Reviews 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/
    
  
    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/| 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 "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 Loading... | |
| 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* closure_tmp_var = EnterTempLocalScope(closure_val); | |
| 2374 // Store function. | |
| 2375 Value* closure_tmp_val = Bind(new LoadLocalInstr(*closure_tmp_var)); | |
| 2376 Value* func_val = | |
| 2377 Bind(new ConstantInstr(Function::ZoneHandle(function.raw()))); | |
| 2378 Do(new StoreInstanceFieldInstr(function_field, | |
| 2379 closure_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* context_tmp_var = EnterTempLocalScope(allocated_context); | |
| 2388 // Store receiver in new context. | |
| 2389 Value* context_tmp_val = Bind(new LoadLocalInstr(*context_tmp_var)); | |
| 
Florian Schneider
2014/02/25 09:21:15
In StoreVMFieldInstr the order of arguments is rev
 | |
| 2390 ValueGraphVisitor for_receiver(owner()); | |
| 2391 node->receiver()->Visit(&for_receiver); | |
| 2392 Append(for_receiver); | |
| 2393 Value* receiver = for_receiver.value(); | |
| 2394 Do(new StoreVMFieldInstr(context_tmp_val, | |
| 2395 Context::variable_offset(0), | |
| 2396 receiver, | |
| 2397 Type::ZoneHandle())); | |
| 2398 // Store new context. | |
| 2399 closure_tmp_val = Bind(new LoadLocalInstr(*closure_tmp_var)); | |
| 2400 context_tmp_val = Bind(new LoadLocalInstr(*context_tmp_var)); | |
| 2401 Do(new StoreInstanceFieldInstr(context_field, | |
| 2402 closure_tmp_val, | |
| 2403 context_tmp_val, | |
| 2404 kEmitStoreBarrier)); | |
| 2405 Do(ExitTempLocalScope(context_tmp_var)); | |
| 2406 } | |
| 2407 ReturnDefinition(ExitTempLocalScope(closure_tmp_var)); | |
| 2408 } | |
| 2355 } | 2409 } | 
| 2356 } | 2410 } | 
| 2357 | 2411 | 
| 2358 | 2412 | 
| 2359 void EffectGraphVisitor::BuildPushArguments( | 2413 void EffectGraphVisitor::BuildPushArguments( | 
| 2360 const ArgumentListNode& node, | 2414 const ArgumentListNode& node, | 
| 2361 ZoneGrowableArray<PushArgumentInstr*>* values) { | 2415 ZoneGrowableArray<PushArgumentInstr*>* values) { | 
| 2362 for (intptr_t i = 0; i < node.length(); ++i) { | 2416 for (intptr_t i = 0; i < node.length(); ++i) { | 
| 2363 ValueGraphVisitor for_argument(owner()); | 2417 ValueGraphVisitor for_argument(owner()); | 
| 2364 node.NodeAt(i)->Visit(&for_argument); | 2418 node.NodeAt(i)->Visit(&for_argument); | 
| (...skipping 1576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3941 LanguageError::kError, | 3995 LanguageError::kError, | 
| 3942 Heap::kNew, | 3996 Heap::kNew, | 
| 3943 "FlowGraphBuilder Bailout: %s %s", | 3997 "FlowGraphBuilder Bailout: %s %s", | 
| 3944 String::Handle(function.name()).ToCString(), | 3998 String::Handle(function.name()).ToCString(), | 
| 3945 reason)); | 3999 reason)); | 
| 3946 Isolate::Current()->long_jump_base()->Jump(1, error); | 4000 Isolate::Current()->long_jump_base()->Jump(1, error); | 
| 3947 } | 4001 } | 
| 3948 | 4002 | 
| 3949 | 4003 | 
| 3950 } // namespace dart | 4004 } // namespace dart | 
| OLD | NEW |