Chromium Code Reviews| 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* 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 Loading... | |
| 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 |
| OLD | NEW |