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/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 853 ASSERT(!token_pos.IsClassifying()); | 853 ASSERT(!token_pos.IsClassifying()); |
| 854 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var(), | 854 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var(), |
| 855 token_pos); | 855 token_pos); |
| 856 } | 856 } |
| 857 | 857 |
| 858 | 858 |
| 859 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, | 859 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, |
| 860 Value* value, | 860 Value* value, |
| 861 TokenPosition token_pos) { | 861 TokenPosition token_pos) { |
| 862 if (local.is_captured()) { | 862 if (local.is_captured()) { |
| 863 LocalVariable* tmp_var = EnterTempLocalScope(value, token_pos); | 863 LocalVariable* tmp_var = EnterTempLocalScope(value); |
| 864 intptr_t delta = | 864 intptr_t delta = |
| 865 owner()->context_level() - local.owner()->context_level(); | 865 owner()->context_level() - local.owner()->context_level(); |
| 866 ASSERT(delta >= 0); | 866 ASSERT(delta >= 0); |
| 867 Value* context = Bind(BuildCurrentContext(token_pos)); | 867 Value* context = Bind(BuildCurrentContext(token_pos)); |
| 868 while (delta-- > 0) { | 868 while (delta-- > 0) { |
| 869 context = Bind(new(Z) LoadFieldInstr( | 869 context = Bind(new(Z) LoadFieldInstr( |
| 870 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()), | 870 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()), |
| 871 token_pos)); | 871 token_pos)); |
| 872 } | 872 } |
| 873 Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var, token_pos)); | 873 Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var, token_pos)); |
| 874 StoreInstanceFieldInstr* store = | 874 StoreInstanceFieldInstr* store = |
| 875 new(Z) StoreInstanceFieldInstr(Context::variable_offset(local.index()), | 875 new(Z) StoreInstanceFieldInstr(Context::variable_offset(local.index()), |
| 876 context, | 876 context, |
| 877 tmp_val, | 877 tmp_val, |
| 878 kEmitStoreBarrier, | 878 kEmitStoreBarrier, |
| 879 token_pos); | 879 token_pos); |
| 880 Do(store); | 880 Do(store); |
| 881 return ExitTempLocalScope(tmp_var, token_pos); | 881 return ExitTempLocalScope(value); |
| 882 } else { | 882 } else { |
| 883 return new(Z) StoreLocalInstr(local, value, token_pos); | 883 return new(Z) StoreLocalInstr(local, value, token_pos); |
| 884 } | 884 } |
| 885 } | 885 } |
| 886 | 886 |
| 887 | 887 |
| 888 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local, | 888 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local, |
| 889 TokenPosition token_pos) { | 889 TokenPosition token_pos) { |
| 890 if (local.IsConst()) { | 890 if (local.IsConst()) { |
| 891 return new(Z) ConstantInstr(*local.ConstValue(), token_pos); | 891 return new(Z) ConstantInstr(*local.ConstValue(), token_pos); |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1311 } | 1311 } |
| 1312 | 1312 |
| 1313 | 1313 |
| 1314 // <Expression> :: Assignable { expr: <Expression> | 1314 // <Expression> :: Assignable { expr: <Expression> |
| 1315 // type: AbstractType | 1315 // type: AbstractType |
| 1316 // dst_name: String } | 1316 // dst_name: String } |
| 1317 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 1317 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 1318 ValueGraphVisitor for_value(owner()); | 1318 ValueGraphVisitor for_value(owner()); |
| 1319 node->expr()->Visit(&for_value); | 1319 node->expr()->Visit(&for_value); |
| 1320 Append(for_value); | 1320 Append(for_value); |
| 1321 Definition* checked_value; | |
| 1322 if (CanSkipTypeCheck(node->expr()->token_pos(), | 1321 if (CanSkipTypeCheck(node->expr()->token_pos(), |
| 1323 for_value.value(), | 1322 for_value.value(), |
| 1324 node->type(), | 1323 node->type(), |
| 1325 node->dst_name())) { | 1324 node->dst_name())) { |
| 1326 // Drop the value and 0 additional temporaries. | 1325 ReturnValue(for_value.value()); |
| 1327 checked_value = new(Z) DropTempsInstr(0, for_value.value()); | |
| 1328 } else { | 1326 } else { |
| 1329 checked_value = BuildAssertAssignable(node->expr()->token_pos(), | 1327 ReturnDefinition(BuildAssertAssignable(node->expr()->token_pos(), |
| 1330 for_value.value(), | 1328 for_value.value(), |
| 1331 node->type(), | 1329 node->type(), |
| 1332 node->dst_name()); | 1330 node->dst_name())); |
| 1333 } | 1331 } |
| 1334 ReturnDefinition(checked_value); | |
| 1335 } | 1332 } |
| 1336 | 1333 |
| 1337 | 1334 |
| 1338 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { | 1335 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) { |
| 1339 ValueGraphVisitor for_value(owner()); | 1336 ValueGraphVisitor for_value(owner()); |
| 1340 node->expr()->Visit(&for_value); | 1337 node->expr()->Visit(&for_value); |
| 1341 Append(for_value); | 1338 Append(for_value); |
| 1342 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), | 1339 ReturnValue(BuildAssignableValue(node->expr()->token_pos(), |
| 1343 for_value.value(), | 1340 for_value.value(), |
| 1344 node->type(), | 1341 node->type(), |
| (...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2238 | 2235 |
| 2239 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { | 2236 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { |
| 2240 return kFirstLocalSlotFromFp | 2237 return kFirstLocalSlotFromFp |
| 2241 - owner()->num_stack_locals() | 2238 - owner()->num_stack_locals() |
| 2242 - owner()->num_copied_params() | 2239 - owner()->num_copied_params() |
| 2243 - owner()->args_pushed() | 2240 - owner()->args_pushed() |
| 2244 - owner()->temp_count() + 1; | 2241 - owner()->temp_count() + 1; |
| 2245 } | 2242 } |
| 2246 | 2243 |
| 2247 | 2244 |
| 2248 LocalVariable* EffectGraphVisitor::EnterTempLocalScope( | 2245 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) { |
| 2249 Value* value, TokenPosition token_pos) { | |
| 2250 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1)); | 2246 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1)); |
| 2251 intptr_t index = GetCurrentTempLocalIndex(); | 2247 intptr_t index = GetCurrentTempLocalIndex(); |
| 2252 char name[64]; | 2248 char name[64]; |
| 2253 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); | 2249 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); |
| 2254 LocalVariable* var = | 2250 LocalVariable* var = |
| 2255 new(Z) LocalVariable(TokenPosition::kNoSource, | 2251 new(Z) LocalVariable(TokenPosition::kNoSource, |
| 2256 String::ZoneHandle(Z, Symbols::New(T, name)), | 2252 String::ZoneHandle(Z, Symbols::New(T, name)), |
| 2257 *value->Type()->ToAbstractType()); | 2253 *value->Type()->ToAbstractType()); |
| 2258 var->set_index(index); | 2254 var->set_index(index); |
| 2259 return var; | 2255 return var; |
| 2260 } | 2256 } |
| 2261 | 2257 |
| 2262 | 2258 |
| 2263 Definition* EffectGraphVisitor::ExitTempLocalScope( | 2259 Definition* EffectGraphVisitor::ExitTempLocalScope(Value* value) { |
| 2264 LocalVariable* var, TokenPosition token_pos) { | 2260 return new(Z) DropTempsInstr(0, value); |
|
Kevin Millikin (Google)
2016/05/10 08:19:47
We can eliminate this Drop instruction if the valu
| |
| 2265 Value* tmp = Bind(new(Z) LoadLocalInstr(*var, token_pos)); | |
| 2266 owner()->DeallocateTemps(1); | |
| 2267 ASSERT(GetCurrentTempLocalIndex() == var->index()); | |
| 2268 return new(Z) DropTempsInstr(1, tmp); | |
| 2269 } | 2261 } |
| 2270 | 2262 |
| 2271 | 2263 |
| 2272 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { | 2264 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { |
| 2273 intptr_t num_temps = node->num_temps(); | 2265 intptr_t num_temps = node->num_temps(); |
| 2274 for (intptr_t i = 0; i < num_temps; ++i) { | 2266 for (intptr_t i = 0; i < num_temps; ++i) { |
| 2275 ValueGraphVisitor for_value(owner()); | 2267 ValueGraphVisitor for_value(owner()); |
| 2276 node->InitializerAt(i)->Visit(&for_value); | 2268 node->InitializerAt(i)->Visit(&for_value); |
| 2277 Append(for_value); | 2269 Append(for_value); |
| 2278 ASSERT(!node->TempAt(i)->HasIndex() || | 2270 ASSERT(!node->TempAt(i)->HasIndex() || |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2330 TypeArguments::ZoneHandle(Z, node->type().arguments()); | 2322 TypeArguments::ZoneHandle(Z, node->type().arguments()); |
| 2331 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), | 2323 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), |
| 2332 type_args); | 2324 type_args); |
| 2333 Value* num_elements = | 2325 Value* num_elements = |
| 2334 Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(node->length())))); | 2326 Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(node->length())))); |
| 2335 CreateArrayInstr* create = new(Z) CreateArrayInstr(node->token_pos(), | 2327 CreateArrayInstr* create = new(Z) CreateArrayInstr(node->token_pos(), |
| 2336 element_type, | 2328 element_type, |
| 2337 num_elements); | 2329 num_elements); |
| 2338 Value* array_val = Bind(create); | 2330 Value* array_val = Bind(create); |
| 2339 | 2331 |
| 2340 { LocalVariable* tmp_var = EnterTempLocalScope(array_val, node->token_pos()); | 2332 { LocalVariable* tmp_var = EnterTempLocalScope(array_val); |
| 2341 const intptr_t class_id = kArrayCid; | 2333 const intptr_t class_id = kArrayCid; |
| 2342 const intptr_t deopt_id = Thread::kNoDeoptId; | 2334 const intptr_t deopt_id = Thread::kNoDeoptId; |
| 2343 for (int i = 0; i < node->length(); ++i) { | 2335 for (int i = 0; i < node->length(); ++i) { |
| 2344 Value* array = Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); | 2336 Value* array = Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); |
| 2345 Value* index = | 2337 Value* index = |
| 2346 Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(i)), | 2338 Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(i)), |
| 2347 node->token_pos())); | 2339 node->token_pos())); |
| 2348 ValueGraphVisitor for_value(owner()); | 2340 ValueGraphVisitor for_value(owner()); |
| 2349 node->ElementAt(i)->Visit(&for_value); | 2341 node->ElementAt(i)->Visit(&for_value); |
| 2350 Append(for_value); | 2342 Append(for_value); |
| 2351 // No store barrier needed for constants. | 2343 // No store barrier needed for constants. |
| 2352 const StoreBarrierType emit_store_barrier = | 2344 const StoreBarrierType emit_store_barrier = |
| 2353 for_value.value()->BindsToConstant() | 2345 for_value.value()->BindsToConstant() |
| 2354 ? kNoStoreBarrier | 2346 ? kNoStoreBarrier |
| 2355 : kEmitStoreBarrier; | 2347 : kEmitStoreBarrier; |
| 2356 const intptr_t index_scale = Instance::ElementSizeFor(class_id); | 2348 const intptr_t index_scale = Instance::ElementSizeFor(class_id); |
| 2357 StoreIndexedInstr* store = new(Z) StoreIndexedInstr( | 2349 StoreIndexedInstr* store = new(Z) StoreIndexedInstr( |
| 2358 array, index, for_value.value(), emit_store_barrier, | 2350 array, index, for_value.value(), emit_store_barrier, |
| 2359 index_scale, class_id, deopt_id, node->token_pos()); | 2351 index_scale, class_id, deopt_id, node->token_pos()); |
| 2360 Do(store); | 2352 Do(store); |
| 2361 } | 2353 } |
| 2362 ReturnDefinition(ExitTempLocalScope(tmp_var, node->token_pos())); | 2354 ReturnDefinition(ExitTempLocalScope(array_val)); |
| 2363 } | 2355 } |
| 2364 } | 2356 } |
| 2365 | 2357 |
| 2366 | 2358 |
| 2367 void EffectGraphVisitor::VisitStringInterpolateNode( | 2359 void EffectGraphVisitor::VisitStringInterpolateNode( |
| 2368 StringInterpolateNode* node) { | 2360 StringInterpolateNode* node) { |
| 2369 ValueGraphVisitor for_argument(owner()); | 2361 ValueGraphVisitor for_argument(owner()); |
| 2370 ArrayNode* arguments = node->value(); | 2362 ArrayNode* arguments = node->value(); |
| 2371 if (arguments->length() == 1) { | 2363 if (arguments->length() == 1) { |
| 2372 ZoneGrowableArray<PushArgumentInstr*>* values = | 2364 ZoneGrowableArray<PushArgumentInstr*>* values = |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2445 const Class& closure_class = | 2437 const Class& closure_class = |
| 2446 Class::ZoneHandle(Z, isolate()->object_store()->closure_class()); | 2438 Class::ZoneHandle(Z, isolate()->object_store()->closure_class()); |
| 2447 ZoneGrowableArray<PushArgumentInstr*>* no_arguments = | 2439 ZoneGrowableArray<PushArgumentInstr*>* no_arguments = |
| 2448 new(Z) ZoneGrowableArray<PushArgumentInstr*>(0); | 2440 new(Z) ZoneGrowableArray<PushArgumentInstr*>(0); |
| 2449 AllocateObjectInstr* alloc = new(Z) AllocateObjectInstr(node->token_pos(), | 2441 AllocateObjectInstr* alloc = new(Z) AllocateObjectInstr(node->token_pos(), |
| 2450 closure_class, | 2442 closure_class, |
| 2451 no_arguments); | 2443 no_arguments); |
| 2452 alloc->set_closure_function(function); | 2444 alloc->set_closure_function(function); |
| 2453 | 2445 |
| 2454 Value* closure_val = Bind(alloc); | 2446 Value* closure_val = Bind(alloc); |
| 2455 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val, | 2447 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val); |
| 2456 node->token_pos()); | |
| 2457 // Store type arguments if scope class is generic. | 2448 // Store type arguments if scope class is generic. |
| 2458 const Type& function_type = Type::ZoneHandle(Z, function.SignatureType()); | 2449 const Type& function_type = Type::ZoneHandle(Z, function.SignatureType()); |
| 2459 const Class& scope_cls = Class::ZoneHandle(Z, function_type.type_class()); | 2450 const Class& scope_cls = Class::ZoneHandle(Z, function_type.type_class()); |
| 2460 if (scope_cls.IsGeneric()) { | 2451 if (scope_cls.IsGeneric()) { |
| 2461 ASSERT(function.Owner() == scope_cls.raw()); | 2452 ASSERT(function.Owner() == scope_cls.raw()); |
| 2462 Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var, | 2453 Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var, |
| 2463 node->token_pos())); | 2454 node->token_pos())); |
| 2464 const Class& instantiator_class = Class::Handle( | 2455 const Class& instantiator_class = Class::Handle( |
| 2465 Z, owner()->function().Owner()); | 2456 Z, owner()->function().Owner()); |
| 2466 Value* type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), | 2457 Value* type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 2482 closure_tmp_val, | 2473 closure_tmp_val, |
| 2483 func_val, | 2474 func_val, |
| 2484 kEmitStoreBarrier, | 2475 kEmitStoreBarrier, |
| 2485 node->token_pos())); | 2476 node->token_pos())); |
| 2486 if (is_implicit) { | 2477 if (is_implicit) { |
| 2487 // Create new context containing the receiver. | 2478 // Create new context containing the receiver. |
| 2488 const intptr_t kNumContextVariables = 1; // The receiver. | 2479 const intptr_t kNumContextVariables = 1; // The receiver. |
| 2489 Value* allocated_context = | 2480 Value* allocated_context = |
| 2490 Bind(new(Z) AllocateContextInstr(node->token_pos(), | 2481 Bind(new(Z) AllocateContextInstr(node->token_pos(), |
| 2491 kNumContextVariables)); | 2482 kNumContextVariables)); |
| 2492 { LocalVariable* context_tmp_var = | 2483 { LocalVariable* context_tmp_var = EnterTempLocalScope(allocated_context); |
| 2493 EnterTempLocalScope(allocated_context, node->token_pos()); | |
| 2494 // Store receiver in context. | 2484 // Store receiver in context. |
| 2495 Value* context_tmp_val = | 2485 Value* context_tmp_val = |
| 2496 Bind(new(Z) LoadLocalInstr(*context_tmp_var, node->token_pos())); | 2486 Bind(new(Z) LoadLocalInstr(*context_tmp_var, node->token_pos())); |
| 2497 ValueGraphVisitor for_receiver(owner()); | 2487 ValueGraphVisitor for_receiver(owner()); |
| 2498 node->receiver()->Visit(&for_receiver); | 2488 node->receiver()->Visit(&for_receiver); |
| 2499 Append(for_receiver); | 2489 Append(for_receiver); |
| 2500 Value* receiver = for_receiver.value(); | 2490 Value* receiver = for_receiver.value(); |
| 2501 Do(new(Z) StoreInstanceFieldInstr(Context::variable_offset(0), | 2491 Do(new(Z) StoreInstanceFieldInstr(Context::variable_offset(0), |
| 2502 context_tmp_val, | 2492 context_tmp_val, |
| 2503 receiver, | 2493 receiver, |
| 2504 kEmitStoreBarrier, | 2494 kEmitStoreBarrier, |
| 2505 node->token_pos())); | 2495 node->token_pos())); |
| 2506 // Store new context in closure. | 2496 // Store new context in closure. |
| 2507 closure_tmp_val = | 2497 closure_tmp_val = |
| 2508 Bind(new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); | 2498 Bind(new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); |
| 2509 context_tmp_val = | 2499 context_tmp_val = |
| 2510 Bind(new(Z) LoadLocalInstr(*context_tmp_var, node->token_pos())); | 2500 Bind(new(Z) LoadLocalInstr(*context_tmp_var, node->token_pos())); |
| 2511 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(), | 2501 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(), |
| 2512 closure_tmp_val, | 2502 closure_tmp_val, |
| 2513 context_tmp_val, | 2503 context_tmp_val, |
| 2514 kEmitStoreBarrier, | 2504 kEmitStoreBarrier, |
| 2515 node->token_pos())); | 2505 node->token_pos())); |
| 2516 Do(ExitTempLocalScope(context_tmp_var, node->token_pos())); | 2506 Do(ExitTempLocalScope(allocated_context)); |
| 2517 } | 2507 } |
| 2518 } else { | 2508 } else { |
| 2519 // Store current context in closure. | 2509 // Store current context in closure. |
| 2520 closure_tmp_val = Bind( | 2510 closure_tmp_val = Bind( |
| 2521 new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); | 2511 new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); |
| 2522 Value* context = Bind(BuildCurrentContext(node->token_pos())); | 2512 Value* context = Bind(BuildCurrentContext(node->token_pos())); |
| 2523 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(), | 2513 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(), |
| 2524 closure_tmp_val, | 2514 closure_tmp_val, |
| 2525 context, | 2515 context, |
| 2526 kEmitStoreBarrier, | 2516 kEmitStoreBarrier, |
| 2527 node->token_pos())); | 2517 node->token_pos())); |
| 2528 } | 2518 } |
| 2529 ReturnDefinition(ExitTempLocalScope(closure_tmp_var, node->token_pos())); | 2519 ReturnDefinition(ExitTempLocalScope(closure_val)); |
| 2530 } | 2520 } |
| 2531 } | 2521 } |
| 2532 | 2522 |
| 2533 | 2523 |
| 2534 void EffectGraphVisitor::BuildPushArguments( | 2524 void EffectGraphVisitor::BuildPushArguments( |
| 2535 const ArgumentListNode& node, | 2525 const ArgumentListNode& node, |
| 2536 ZoneGrowableArray<PushArgumentInstr*>* values) { | 2526 ZoneGrowableArray<PushArgumentInstr*>* values) { |
| 2537 for (intptr_t i = 0; i < node.length(); ++i) { | 2527 for (intptr_t i = 0; i < node.length(); ++i) { |
| 2538 ValueGraphVisitor for_argument(owner()); | 2528 ValueGraphVisitor for_argument(owner()); |
| 2539 node.NodeAt(i)->Visit(&for_argument); | 2529 node.NodeAt(i)->Visit(&for_argument); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2680 ReturnDefinition(call); | 2670 ReturnDefinition(call); |
| 2681 } | 2671 } |
| 2682 | 2672 |
| 2683 | 2673 |
| 2684 void EffectGraphVisitor::BuildClosureCall( | 2674 void EffectGraphVisitor::BuildClosureCall( |
| 2685 ClosureCallNode* node, bool result_needed) { | 2675 ClosureCallNode* node, bool result_needed) { |
| 2686 ValueGraphVisitor for_closure(owner()); | 2676 ValueGraphVisitor for_closure(owner()); |
| 2687 node->closure()->Visit(&for_closure); | 2677 node->closure()->Visit(&for_closure); |
| 2688 Append(for_closure); | 2678 Append(for_closure); |
| 2689 | 2679 |
| 2690 LocalVariable* tmp_var = | 2680 Value* closure_value = for_closure.value(); |
| 2691 EnterTempLocalScope(for_closure.value(), node->token_pos()); | 2681 LocalVariable* tmp_var = EnterTempLocalScope(closure_value); |
| 2692 | 2682 |
| 2693 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2683 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2694 new(Z) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 2684 new(Z) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 2695 Value* closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); | 2685 Value* closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); |
| 2696 PushArgumentInstr* push_closure = PushArgument(closure_val); | 2686 PushArgumentInstr* push_closure = PushArgument(closure_val); |
| 2697 arguments->Add(push_closure); | 2687 arguments->Add(push_closure); |
| 2698 BuildPushArguments(*node->arguments(), arguments); | 2688 BuildPushArguments(*node->arguments(), arguments); |
| 2699 | 2689 |
| 2700 closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); | 2690 closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); |
| 2701 LoadFieldInstr* function_load = new(Z) LoadFieldInstr( | 2691 LoadFieldInstr* function_load = new(Z) LoadFieldInstr( |
| 2702 closure_val, | 2692 closure_val, |
| 2703 Closure::function_offset(), | 2693 Closure::function_offset(), |
| 2704 AbstractType::ZoneHandle(Z, AbstractType::null()), | 2694 AbstractType::ZoneHandle(Z, AbstractType::null()), |
| 2705 node->token_pos()); | 2695 node->token_pos()); |
| 2706 function_load->set_is_immutable(true); | 2696 function_load->set_is_immutable(true); |
| 2707 Value* function_val = Bind(function_load); | 2697 Value* function_val = Bind(function_load); |
| 2708 | 2698 |
| 2709 Definition* closure_call = | 2699 Definition* closure_call = |
| 2710 new(Z) ClosureCallInstr(function_val, node, arguments); | 2700 new(Z) ClosureCallInstr(function_val, node, arguments); |
| 2711 if (result_needed) { | 2701 if (result_needed) { |
| 2712 Value* result = Bind(closure_call); | 2702 Value* result = Bind(closure_call); |
| 2713 Do(new(Z) StoreLocalInstr(*tmp_var, result, ST(node->token_pos()))); | 2703 Do(new(Z) StoreLocalInstr(*tmp_var, result, ST(node->token_pos()))); |
| 2714 } else { | 2704 } else { |
| 2715 Do(closure_call); | 2705 Do(closure_call); |
| 2716 } | 2706 } |
| 2717 ReturnDefinition(ExitTempLocalScope(tmp_var, node->token_pos())); | 2707 ReturnDefinition(ExitTempLocalScope(closure_value)); |
| 2718 } | 2708 } |
| 2719 | 2709 |
| 2720 | 2710 |
| 2721 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 2711 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 2722 BuildClosureCall(node, false); | 2712 BuildClosureCall(node, false); |
| 2723 } | 2713 } |
| 2724 | 2714 |
| 2725 | 2715 |
| 2726 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 2716 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 2727 BuildClosureCall(node, true); | 2717 BuildClosureCall(node, true); |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2946 | 2936 |
| 2947 // t_n contains the allocated and initialized object. | 2937 // t_n contains the allocated and initialized object. |
| 2948 // t_n <- AllocateObject(class) | 2938 // t_n <- AllocateObject(class) |
| 2949 // t_n <- StoreLocal(temp, t_n); | 2939 // t_n <- StoreLocal(temp, t_n); |
| 2950 // t_n+1 <- ctor-arg | 2940 // t_n+1 <- ctor-arg |
| 2951 // t_n+2... <- constructor arguments start here | 2941 // t_n+2... <- constructor arguments start here |
| 2952 // StaticCall(constructor, t_n, t_n+1, ...) | 2942 // StaticCall(constructor, t_n, t_n+1, ...) |
| 2953 // tn <- LoadLocal(temp) | 2943 // tn <- LoadLocal(temp) |
| 2954 | 2944 |
| 2955 Value* allocate = BuildObjectAllocation(node); | 2945 Value* allocate = BuildObjectAllocation(node); |
| 2956 { LocalVariable* tmp_var = EnterTempLocalScope(allocate, node->token_pos()); | 2946 { LocalVariable* tmp_var = EnterTempLocalScope(allocate); |
| 2957 Value* allocated_tmp = | 2947 Value* allocated_tmp = |
| 2958 Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); | 2948 Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); |
| 2959 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); | 2949 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); |
| 2960 BuildConstructorCall(node, push_allocated_value); | 2950 BuildConstructorCall(node, push_allocated_value); |
| 2961 ReturnDefinition(ExitTempLocalScope(tmp_var, node->token_pos())); | 2951 ReturnDefinition(ExitTempLocalScope(allocate)); |
| 2962 } | 2952 } |
| 2963 } | 2953 } |
| 2964 | 2954 |
| 2965 | 2955 |
| 2966 | 2956 |
| 2967 void EffectGraphVisitor::BuildInstanceGetterConditional( | 2957 void EffectGraphVisitor::BuildInstanceGetterConditional( |
| 2968 InstanceGetterNode* node) { | 2958 InstanceGetterNode* node) { |
| 2969 const TokenPosition token_pos = node->token_pos(); | 2959 const TokenPosition token_pos = node->token_pos(); |
| 2970 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); | 2960 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); |
| 2971 LoadLocalNode* load_temp = new(Z) LoadLocalNode(token_pos, temp_var); | 2961 LoadLocalNode* load_temp = new(Z) LoadLocalNode(token_pos, temp_var); |
| (...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3967 ASSERT((node->label() == NULL) || !is_top_level_sequence); | 3957 ASSERT((node->label() == NULL) || !is_top_level_sequence); |
| 3968 NestedBlock nested_block(owner(), node); | 3958 NestedBlock nested_block(owner(), node); |
| 3969 | 3959 |
| 3970 if (num_context_variables > 0) { | 3960 if (num_context_variables > 0) { |
| 3971 // The local scope declares variables that are captured. | 3961 // The local scope declares variables that are captured. |
| 3972 // Allocate and chain a new context (Except don't chain when at the function | 3962 // Allocate and chain a new context (Except don't chain when at the function |
| 3973 // entry if the function does not capture any variables from outer scopes). | 3963 // entry if the function does not capture any variables from outer scopes). |
| 3974 Value* allocated_context = | 3964 Value* allocated_context = |
| 3975 Bind(new(Z) AllocateContextInstr(node->token_pos(), | 3965 Bind(new(Z) AllocateContextInstr(node->token_pos(), |
| 3976 num_context_variables)); | 3966 num_context_variables)); |
| 3977 { LocalVariable* tmp_var = | 3967 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); |
| 3978 EnterTempLocalScope(allocated_context, node->token_pos()); | |
| 3979 if (!is_top_level_sequence || HasContextScope()) { | 3968 if (!is_top_level_sequence || HasContextScope()) { |
| 3980 ASSERT(is_top_level_sequence || | 3969 ASSERT(is_top_level_sequence || |
| 3981 (nested_block.ContextLevel() == | 3970 (nested_block.ContextLevel() == |
| 3982 nested_block.outer()->ContextLevel() + 1)); | 3971 nested_block.outer()->ContextLevel() + 1)); |
| 3983 Value* tmp_val = Bind( | 3972 Value* tmp_val = Bind( |
| 3984 new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); | 3973 new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); |
| 3985 Value* parent_context = Bind(BuildCurrentContext(node->token_pos())); | 3974 Value* parent_context = Bind(BuildCurrentContext(node->token_pos())); |
| 3986 Do(new(Z) StoreInstanceFieldInstr(Context::parent_offset(), | 3975 Do(new(Z) StoreInstanceFieldInstr(Context::parent_offset(), |
| 3987 tmp_val, | 3976 tmp_val, |
| 3988 parent_context, | 3977 parent_context, |
| 3989 kEmitStoreBarrier, | 3978 kEmitStoreBarrier, |
| 3990 node->token_pos())); | 3979 node->token_pos())); |
| 3991 } | 3980 } |
| 3992 Do(BuildStoreContext( | 3981 Do(BuildStoreContext( |
| 3993 Bind(ExitTempLocalScope(tmp_var, node->token_pos())), | 3982 Bind(ExitTempLocalScope(allocated_context)), |
| 3994 node->token_pos())); | 3983 node->token_pos())); |
| 3995 } | 3984 } |
| 3996 | 3985 |
| 3997 // If this node_sequence is the body of the function being compiled, copy | 3986 // If this node_sequence is the body of the function being compiled, copy |
| 3998 // the captured parameters from the frame into the context. | 3987 // the captured parameters from the frame into the context. |
| 3999 if (is_top_level_sequence) { | 3988 if (is_top_level_sequence) { |
| 4000 ASSERT(scope->context_level() == 1); | 3989 ASSERT(scope->context_level() == 1); |
| 4001 const int num_params = function.NumParameters(); | 3990 const int num_params = function.NumParameters(); |
| 4002 int param_frame_index = (num_params == function.num_fixed_parameters()) ? | 3991 int param_frame_index = (num_params == function.num_fixed_parameters()) ? |
| 4003 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; | 3992 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; |
| (...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4610 Script::Handle(function.script()), | 4599 Script::Handle(function.script()), |
| 4611 function.token_pos(), | 4600 function.token_pos(), |
| 4612 Report::AtLocation, | 4601 Report::AtLocation, |
| 4613 "FlowGraphBuilder Bailout: %s %s", | 4602 "FlowGraphBuilder Bailout: %s %s", |
| 4614 String::Handle(function.name()).ToCString(), | 4603 String::Handle(function.name()).ToCString(), |
| 4615 reason); | 4604 reason); |
| 4616 UNREACHABLE(); | 4605 UNREACHABLE(); |
| 4617 } | 4606 } |
| 4618 | 4607 |
| 4619 } // namespace dart | 4608 } // namespace dart |
| OLD | NEW |