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/code_descriptors.h" | 9 #include "vm/code_descriptors.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 // All parameters are copied if any parameter is. | 50 // All parameters are copied if any parameter is. |
51 num_non_copied_params_((num_copied_params_ == 0) | 51 num_non_copied_params_((num_copied_params_ == 0) |
52 ? parsed_function.function().num_fixed_parameters() | 52 ? parsed_function.function().num_fixed_parameters() |
53 : 0), | 53 : 0), |
54 num_stack_locals_(parsed_function.num_stack_locals()), | 54 num_stack_locals_(parsed_function.num_stack_locals()), |
55 exit_collector_(exit_collector), | 55 exit_collector_(exit_collector), |
56 last_used_block_id_(0), // 0 is used for the graph entry. | 56 last_used_block_id_(0), // 0 is used for the graph entry. |
57 context_level_(0), | 57 context_level_(0), |
58 last_used_try_index_(CatchClauseNode::kInvalidTryIndex), | 58 last_used_try_index_(CatchClauseNode::kInvalidTryIndex), |
59 try_index_(CatchClauseNode::kInvalidTryIndex), | 59 try_index_(CatchClauseNode::kInvalidTryIndex), |
60 graph_entry_(NULL) { } | 60 graph_entry_(NULL), |
| 61 args_pushed_(0) { } |
61 | 62 |
62 | 63 |
63 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) { | 64 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) { |
64 graph_entry_->AddCatchEntry(entry); | 65 graph_entry_->AddCatchEntry(entry); |
65 } | 66 } |
66 | 67 |
67 | 68 |
68 void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) { | 69 void InlineExitCollector::PrepareGraphs(FlowGraph* callee_graph) { |
69 ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1); | 70 ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1); |
70 ASSERT(callee_graph->max_block_id() > caller_graph_->max_block_id()); | 71 ASSERT(callee_graph->max_block_id() > caller_graph_->max_block_id()); |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 } | 350 } |
350 temp_index_ = other_fragment.temp_index(); | 351 temp_index_ = other_fragment.temp_index(); |
351 } | 352 } |
352 | 353 |
353 | 354 |
354 Value* EffectGraphVisitor::Bind(Definition* definition) { | 355 Value* EffectGraphVisitor::Bind(Definition* definition) { |
355 ASSERT(is_open()); | 356 ASSERT(is_open()); |
356 DeallocateTempIndex(definition->InputCount()); | 357 DeallocateTempIndex(definition->InputCount()); |
357 definition->set_use_kind(Definition::kValue); | 358 definition->set_use_kind(Definition::kValue); |
358 definition->set_temp_index(AllocateTempIndex()); | 359 definition->set_temp_index(AllocateTempIndex()); |
| 360 owner_->add_args_pushed(-definition->ArgumentCount()); |
359 if (is_empty()) { | 361 if (is_empty()) { |
360 entry_ = definition; | 362 entry_ = definition; |
361 } else { | 363 } else { |
362 exit()->LinkTo(definition); | 364 exit()->LinkTo(definition); |
363 } | 365 } |
364 exit_ = definition; | 366 exit_ = definition; |
365 return new Value(definition); | 367 return new Value(definition); |
366 } | 368 } |
367 | 369 |
368 | 370 |
369 void EffectGraphVisitor::Do(Definition* definition) { | 371 void EffectGraphVisitor::Do(Definition* definition) { |
370 ASSERT(is_open()); | 372 ASSERT(is_open()); |
371 DeallocateTempIndex(definition->InputCount()); | 373 DeallocateTempIndex(definition->InputCount()); |
372 definition->set_use_kind(Definition::kEffect); | 374 definition->set_use_kind(Definition::kEffect); |
| 375 owner_->add_args_pushed(-definition->ArgumentCount()); |
373 if (is_empty()) { | 376 if (is_empty()) { |
374 entry_ = definition; | 377 entry_ = definition; |
375 } else { | 378 } else { |
376 exit()->LinkTo(definition); | 379 exit()->LinkTo(definition); |
377 } | 380 } |
378 exit_ = definition; | 381 exit_ = definition; |
379 } | 382 } |
380 | 383 |
381 | 384 |
382 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { | 385 void EffectGraphVisitor::AddInstruction(Instruction* instruction) { |
383 ASSERT(is_open()); | 386 ASSERT(is_open()); |
384 ASSERT(instruction->IsPushArgument() || !instruction->IsDefinition()); | 387 ASSERT(instruction->IsPushArgument() || !instruction->IsDefinition()); |
385 ASSERT(!instruction->IsBlockEntry()); | 388 ASSERT(!instruction->IsBlockEntry()); |
386 DeallocateTempIndex(instruction->InputCount()); | 389 DeallocateTempIndex(instruction->InputCount()); |
| 390 owner_->add_args_pushed(-instruction->ArgumentCount()); |
387 if (is_empty()) { | 391 if (is_empty()) { |
388 entry_ = exit_ = instruction; | 392 entry_ = exit_ = instruction; |
389 } else { | 393 } else { |
390 exit()->LinkTo(instruction); | 394 exit()->LinkTo(instruction); |
391 exit_ = instruction; | 395 exit_ = instruction; |
392 } | 396 } |
393 } | 397 } |
394 | 398 |
395 | 399 |
396 void EffectGraphVisitor::AddReturnExit(intptr_t token_pos, Value* value) { | 400 void EffectGraphVisitor::AddReturnExit(intptr_t token_pos, Value* value) { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 } | 500 } |
497 | 501 |
498 // 3. Set the exit to the graph to be the false successor of the test, a | 502 // 3. Set the exit to the graph to be the false successor of the test, a |
499 // fresh target node | 503 // fresh target node |
500 | 504 |
501 exit_ = test_fragment.CreateFalseSuccessor(); | 505 exit_ = test_fragment.CreateFalseSuccessor(); |
502 } | 506 } |
503 | 507 |
504 | 508 |
505 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { | 509 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { |
| 510 owner_->add_args_pushed(1); |
506 PushArgumentInstr* result = new PushArgumentInstr(value); | 511 PushArgumentInstr* result = new PushArgumentInstr(value); |
507 AddInstruction(result); | 512 AddInstruction(result); |
508 return result; | 513 return result; |
509 } | 514 } |
510 | 515 |
511 | 516 |
512 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local, | 517 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local, |
513 Value* value) { | 518 Value* value) { |
514 ASSERT(!local.is_captured()); | 519 ASSERT(!local.is_captured()); |
515 return new StoreLocalInstr(local, value); | 520 return new StoreLocalInstr(local, value); |
(...skipping 1301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1817 ArgumentDefinitionTestNode* node) { | 1822 ArgumentDefinitionTestNode* node) { |
1818 InlineBailout("EffectGraphVisitor::VisitArgumentDefinitionTestNode"); | 1823 InlineBailout("EffectGraphVisitor::VisitArgumentDefinitionTestNode"); |
1819 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor()); | 1824 Definition* load = BuildLoadLocal(node->saved_arguments_descriptor()); |
1820 Value* arguments_descriptor = Bind(load); | 1825 Value* arguments_descriptor = Bind(load); |
1821 ArgumentDefinitionTestInstr* arg_def_test = | 1826 ArgumentDefinitionTestInstr* arg_def_test = |
1822 new ArgumentDefinitionTestInstr(node, arguments_descriptor); | 1827 new ArgumentDefinitionTestInstr(node, arguments_descriptor); |
1823 ReturnDefinition(arg_def_test); | 1828 ReturnDefinition(arg_def_test); |
1824 } | 1829 } |
1825 | 1830 |
1826 | 1831 |
| 1832 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { |
| 1833 return kFirstLocalSlotFromFp |
| 1834 - owner()->num_stack_locals() |
| 1835 - owner()->num_copied_params() |
| 1836 - owner()->args_pushed() |
| 1837 - temp_index() + 1; |
| 1838 } |
| 1839 |
| 1840 |
| 1841 class TempLocalScope : public ValueObject { |
| 1842 public: |
| 1843 TempLocalScope(EffectGraphVisitor* visitor, Value* value) |
| 1844 : visitor_(visitor) { |
| 1845 ASSERT(value->definition()->temp_index() == visitor->temp_index() - 1); |
| 1846 intptr_t index = visitor->GetCurrentTempLocalIndex(); |
| 1847 char name[64]; |
| 1848 OS::SNPrint(name, 64, ":tmp_local%"Pd, index); |
| 1849 var_ = new LocalVariable(0, String::ZoneHandle(Symbols::New(name)), |
| 1850 Type::ZoneHandle(Type::DynamicType())); |
| 1851 var_->set_index(index); |
| 1852 visitor->Do(new PushTempInstr(value)); |
| 1853 visitor->AllocateTempIndex(); |
| 1854 } |
| 1855 |
| 1856 LocalVariable* var() const { return var_; } |
| 1857 |
| 1858 ~TempLocalScope() { |
| 1859 Value* result = visitor_->Bind(new LoadLocalInstr(*var_)); |
| 1860 visitor_->DeallocateTempIndex(1); |
| 1861 visitor_->ReturnDefinition(new DropTempsInstr(1, result)); |
| 1862 } |
| 1863 |
| 1864 private: |
| 1865 EffectGraphVisitor* visitor_; |
| 1866 Value* value_; |
| 1867 LocalVariable* var_; |
| 1868 }; |
| 1869 |
| 1870 |
| 1871 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { |
| 1872 intptr_t num_temps = node->num_temps(); |
| 1873 for (intptr_t i = 0; i < num_temps; ++i) { |
| 1874 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1875 node->InitializerAt(i)->Visit(&for_value); |
| 1876 Append(for_value); |
| 1877 Value* temp_val = for_value.value(); |
| 1878 node->TempAt(i)->set_index(GetCurrentTempLocalIndex()); |
| 1879 Do(new PushTempInstr(temp_val)); |
| 1880 AllocateTempIndex(); |
| 1881 } |
| 1882 } |
| 1883 |
| 1884 |
| 1885 void EffectGraphVisitor::VisitLetNode(LetNode* node) { |
| 1886 BuildLetTempExpressions(node); |
| 1887 intptr_t num_temps = node->num_temps(); |
| 1888 |
| 1889 // TODO(fschneider): Generate better code for effect context by visiting the |
| 1890 // body for effect. Currently, the value of the body expression is |
| 1891 // materialized and then dropped. This also requires changing DropTempsInstr |
| 1892 // to have zero or one inputs. |
| 1893 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1894 node->body()->Visit(&for_value); |
| 1895 Append(for_value); |
| 1896 Value* result_value = for_value.value(); |
| 1897 DeallocateTempIndex(num_temps); |
| 1898 Do(new DropTempsInstr(num_temps, result_value)); |
| 1899 } |
| 1900 |
| 1901 |
| 1902 void ValueGraphVisitor::VisitLetNode(LetNode* node) { |
| 1903 BuildLetTempExpressions(node); |
| 1904 |
| 1905 ValueGraphVisitor for_value(owner(), temp_index()); |
| 1906 node->body()->Visit(&for_value); |
| 1907 Append(for_value); |
| 1908 Value* result_value = for_value.value(); |
| 1909 intptr_t num_temps = node->num_temps(); |
| 1910 if (num_temps > 0) { |
| 1911 DeallocateTempIndex(num_temps); |
| 1912 ReturnDefinition(new DropTempsInstr(num_temps, result_value)); |
| 1913 } else { |
| 1914 ReturnValue(result_value); |
| 1915 } |
| 1916 } |
| 1917 |
| 1918 |
1827 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { | 1919 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
1828 const AbstractTypeArguments& type_args = | 1920 const AbstractTypeArguments& type_args = |
1829 AbstractTypeArguments::ZoneHandle(node->type().arguments()); | 1921 AbstractTypeArguments::ZoneHandle(node->type().arguments()); |
1830 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), | 1922 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), |
1831 type_args); | 1923 type_args); |
1832 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), | 1924 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), |
1833 node->length(), | 1925 node->length(), |
1834 node->type(), | 1926 node->type(), |
1835 element_type); | 1927 element_type); |
1836 Value* array_val = Bind(create); | 1928 Value* array_val = Bind(create); |
1837 Definition* store = BuildStoreTemp(node->temp_local(), array_val); | |
1838 Do(store); | |
1839 | 1929 |
1840 const intptr_t class_id = create->Type()->ToCid(); | 1930 { TempLocalScope tmp(this, array_val); |
1841 const intptr_t deopt_id = Isolate::kNoDeoptId; | 1931 const intptr_t class_id = create->Type()->ToCid(); |
1842 for (int i = 0; i < node->length(); ++i) { | 1932 const intptr_t deopt_id = Isolate::kNoDeoptId; |
1843 Value* array = Bind( | 1933 for (int i = 0; i < node->length(); ++i) { |
1844 new LoadLocalInstr(node->temp_local())); | 1934 Value* array = Bind(new LoadLocalInstr(*tmp.var())); |
1845 Value* index = Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(i)))); | 1935 Value* index = Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(i)))); |
1846 ValueGraphVisitor for_value(owner(), temp_index()); | 1936 ValueGraphVisitor for_value(owner(), temp_index()); |
1847 node->ElementAt(i)->Visit(&for_value); | 1937 node->ElementAt(i)->Visit(&for_value); |
1848 Append(for_value); | 1938 Append(for_value); |
1849 // No store barrier needed for constants. | 1939 // No store barrier needed for constants. |
1850 const StoreBarrierType emit_store_barrier = | 1940 const StoreBarrierType emit_store_barrier = |
1851 for_value.value()->BindsToConstant() | 1941 for_value.value()->BindsToConstant() |
1852 ? kNoStoreBarrier | 1942 ? kNoStoreBarrier |
1853 : kEmitStoreBarrier; | 1943 : kEmitStoreBarrier; |
1854 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id); | 1944 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(class_id); |
1855 StoreIndexedInstr* store = new StoreIndexedInstr( | 1945 StoreIndexedInstr* store = new StoreIndexedInstr( |
1856 array, index, for_value.value(), | 1946 array, index, for_value.value(), |
1857 emit_store_barrier, index_scale, class_id, deopt_id); | 1947 emit_store_barrier, index_scale, class_id, deopt_id); |
1858 Do(store); | 1948 Do(store); |
| 1949 } |
1859 } | 1950 } |
1860 | |
1861 ReturnDefinition(new LoadLocalInstr(node->temp_local())); | |
1862 } | 1951 } |
1863 | 1952 |
1864 | 1953 |
1865 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { | 1954 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { |
1866 const Function& function = node->function(); | 1955 const Function& function = node->function(); |
1867 | 1956 |
1868 if (function.IsImplicitStaticClosureFunction()) { | 1957 if (function.IsImplicitStaticClosureFunction()) { |
1869 Instance& closure = Instance::ZoneHandle(); | 1958 Instance& closure = Instance::ZoneHandle(); |
1870 closure ^= function.implicit_static_closure(); | 1959 closure ^= function.implicit_static_closure(); |
1871 if (closure.IsNull()) { | 1960 if (closure.IsNull()) { |
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2325 // No instantiator required. | 2414 // No instantiator required. |
2326 Value* instantiator_val = Bind(new ConstantInstr( | 2415 Value* instantiator_val = Bind(new ConstantInstr( |
2327 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); | 2416 Smi::ZoneHandle(Smi::New(StubCode::kNoInstantiator)))); |
2328 call_arguments->Add(PushArgument(instantiator_val)); | 2417 call_arguments->Add(PushArgument(instantiator_val)); |
2329 return; | 2418 return; |
2330 } | 2419 } |
2331 | 2420 |
2332 // The type arguments are uninstantiated. We use expression_temp_var to save | 2421 // The type arguments are uninstantiated. We use expression_temp_var to save |
2333 // the instantiator type arguments because they have two uses. | 2422 // the instantiator type arguments because they have two uses. |
2334 ASSERT(owner()->parsed_function().expression_temp_var() != NULL); | 2423 ASSERT(owner()->parsed_function().expression_temp_var() != NULL); |
2335 const LocalVariable& temp = *owner()->parsed_function().expression_temp_var(); | |
2336 const Class& instantiator_class = Class::Handle( | 2424 const Class& instantiator_class = Class::Handle( |
2337 owner()->parsed_function().function().Owner()); | 2425 owner()->parsed_function().function().Owner()); |
2338 Value* type_arguments_val = BuildInstantiatorTypeArguments( | 2426 Value* type_arguments_val = BuildInstantiatorTypeArguments( |
2339 node->token_pos(), instantiator_class, NULL); | 2427 node->token_pos(), instantiator_class, NULL); |
2340 | 2428 |
2341 const bool use_instantiator_type_args = | 2429 const bool use_instantiator_type_args = |
2342 node->type_arguments().IsUninstantiatedIdentity() || | 2430 node->type_arguments().IsUninstantiatedIdentity() || |
2343 node->type_arguments().CanShareInstantiatorTypeArguments( | 2431 node->type_arguments().CanShareInstantiatorTypeArguments( |
2344 instantiator_class); | 2432 instantiator_class); |
2345 | 2433 |
2346 if (!use_instantiator_type_args) { | 2434 if (!use_instantiator_type_args) { |
2347 const intptr_t len = node->type_arguments().Length(); | 2435 const intptr_t len = node->type_arguments().Length(); |
2348 if (node->type_arguments().IsRawInstantiatedRaw(len)) { | 2436 if (node->type_arguments().IsRawInstantiatedRaw(len)) { |
2349 type_arguments_val = | 2437 type_arguments_val = |
2350 Bind(BuildStoreTemp(temp, type_arguments_val)); | 2438 Bind(BuildStoreExprTemp(type_arguments_val)); |
2351 type_arguments_val = Bind( | 2439 type_arguments_val = Bind( |
2352 new ExtractConstructorTypeArgumentsInstr( | 2440 new ExtractConstructorTypeArgumentsInstr( |
2353 node->token_pos(), | 2441 node->token_pos(), |
2354 node->type_arguments(), | 2442 node->type_arguments(), |
2355 instantiator_class, | 2443 instantiator_class, |
2356 type_arguments_val)); | 2444 type_arguments_val)); |
2357 } else { | 2445 } else { |
2358 Do(BuildStoreTemp(temp, type_arguments_val)); | 2446 Do(BuildStoreExprTemp(type_arguments_val)); |
2359 type_arguments_val = Bind(new ConstantInstr(node->type_arguments())); | 2447 type_arguments_val = Bind(new ConstantInstr(node->type_arguments())); |
2360 } | 2448 } |
2361 } | 2449 } |
2362 call_arguments->Add(PushArgument(type_arguments_val)); | 2450 call_arguments->Add(PushArgument(type_arguments_val)); |
2363 | 2451 |
2364 Value* instantiator_val = NULL; | 2452 Value* instantiator_val = NULL; |
2365 if (!use_instantiator_type_args) { | 2453 if (!use_instantiator_type_args) { |
2366 instantiator_val = Bind(BuildLoadLocal(temp)); | 2454 instantiator_val = Bind(BuildLoadExprTemp()); |
2367 const intptr_t len = node->type_arguments().Length(); | 2455 const intptr_t len = node->type_arguments().Length(); |
2368 if (node->type_arguments().IsRawInstantiatedRaw(len)) { | 2456 if (node->type_arguments().IsRawInstantiatedRaw(len)) { |
2369 instantiator_val = | 2457 instantiator_val = |
2370 Bind(new ExtractConstructorInstantiatorInstr(node, | 2458 Bind(new ExtractConstructorInstantiatorInstr(node, |
2371 instantiator_class, | 2459 instantiator_class, |
2372 instantiator_val)); | 2460 instantiator_val)); |
2373 } | 2461 } |
2374 } else { | 2462 } else { |
2375 // No instantiator required. | 2463 // No instantiator required. |
2376 instantiator_val = Bind(new ConstantInstr( | 2464 instantiator_val = Bind(new ConstantInstr( |
(...skipping 11 matching lines...) Expand all Loading... |
2388 | 2476 |
2389 // t_n contains the allocated and initialized object. | 2477 // t_n contains the allocated and initialized object. |
2390 // t_n <- AllocateObject(class) | 2478 // t_n <- AllocateObject(class) |
2391 // t_n <- StoreLocal(temp, t_n); | 2479 // t_n <- StoreLocal(temp, t_n); |
2392 // t_n+1 <- ctor-arg | 2480 // t_n+1 <- ctor-arg |
2393 // t_n+2... <- constructor arguments start here | 2481 // t_n+2... <- constructor arguments start here |
2394 // StaticCall(constructor, t_n, t_n+1, ...) | 2482 // StaticCall(constructor, t_n, t_n+1, ...) |
2395 // tn <- LoadLocal(temp) | 2483 // tn <- LoadLocal(temp) |
2396 | 2484 |
2397 Value* allocate = BuildObjectAllocation(node); | 2485 Value* allocate = BuildObjectAllocation(node); |
2398 Value* allocated_value = Bind(BuildStoreTemp( | 2486 { TempLocalScope tmp(this, allocate); |
2399 node->allocated_object_var(), | 2487 Value* allocated_tmp = Bind(new LoadLocalInstr(*tmp.var())); |
2400 allocate)); | 2488 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); |
2401 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 2489 BuildConstructorCall(node, push_allocated_value); |
2402 BuildConstructorCall(node, push_allocated_value); | 2490 } |
2403 Definition* load_allocated = BuildLoadLocal( | |
2404 node->allocated_object_var()); | |
2405 allocated_value = Bind(load_allocated); | |
2406 ReturnValue(allocated_value); | |
2407 } | 2491 } |
2408 | 2492 |
2409 | 2493 |
2410 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 2494 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
2411 ValueGraphVisitor for_receiver(owner(), temp_index()); | 2495 ValueGraphVisitor for_receiver(owner(), temp_index()); |
2412 node->receiver()->Visit(&for_receiver); | 2496 node->receiver()->Visit(&for_receiver); |
2413 Append(for_receiver); | 2497 Append(for_receiver); |
2414 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 2498 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
2415 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2499 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
2416 new ZoneGrowableArray<PushArgumentInstr*>(1); | 2500 new ZoneGrowableArray<PushArgumentInstr*>(1); |
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3263 arguments->Add(new LiteralNode(args_pos, method_name)); | 3347 arguments->Add(new LiteralNode(args_pos, method_name)); |
3264 // The second argument is the arguments descriptor of the original method. | 3348 // The second argument is the arguments descriptor of the original method. |
3265 const Array& args_descriptor = | 3349 const Array& args_descriptor = |
3266 Array::ZoneHandle(ArgumentsDescriptor::New(method_arguments->length(), | 3350 Array::ZoneHandle(ArgumentsDescriptor::New(method_arguments->length(), |
3267 method_arguments->names())); | 3351 method_arguments->names())); |
3268 arguments->Add(new LiteralNode(args_pos, args_descriptor)); | 3352 arguments->Add(new LiteralNode(args_pos, args_descriptor)); |
3269 // The third argument is an array containing the original method arguments, | 3353 // The third argument is an array containing the original method arguments, |
3270 // including the receiver. | 3354 // including the receiver. |
3271 ArrayNode* args_array = new ArrayNode( | 3355 ArrayNode* args_array = new ArrayNode( |
3272 args_pos, | 3356 args_pos, |
3273 Type::ZoneHandle(Type::ArrayType()), | 3357 Type::ZoneHandle(Type::ArrayType())); |
3274 *owner()->parsed_function().array_literal_var()); | |
3275 for (intptr_t i = 0; i < method_arguments->length(); i++) { | 3358 for (intptr_t i = 0; i < method_arguments->length(); i++) { |
3276 args_array->AddElement(method_arguments->NodeAt(i)); | 3359 args_array->AddElement(method_arguments->NodeAt(i)); |
3277 } | 3360 } |
3278 arguments->Add(args_array); | 3361 arguments->Add(args_array); |
3279 ZoneGrowableArray<PushArgumentInstr*>* allocation_args = | 3362 ZoneGrowableArray<PushArgumentInstr*>* allocation_args = |
3280 new ZoneGrowableArray<PushArgumentInstr*>(arguments->length()); | 3363 new ZoneGrowableArray<PushArgumentInstr*>(arguments->length()); |
3281 BuildPushArguments(*arguments, allocation_args); | 3364 BuildPushArguments(*arguments, allocation_args); |
3282 StaticCallInstr* allocation = new StaticCallInstr(args_pos, | 3365 StaticCallInstr* allocation = new StaticCallInstr(args_pos, |
3283 allocation_function, | 3366 allocation_function, |
3284 Array::ZoneHandle(), | 3367 Array::ZoneHandle(), |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3459 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3542 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
3460 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3543 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
3461 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3544 OS::SNPrint(chars, len, kFormat, function_name, reason); |
3462 const Error& error = Error::Handle( | 3545 const Error& error = Error::Handle( |
3463 LanguageError::New(String::Handle(String::New(chars)))); | 3546 LanguageError::New(String::Handle(String::New(chars)))); |
3464 Isolate::Current()->long_jump_base()->Jump(1, error); | 3547 Isolate::Current()->long_jump_base()->Jump(1, error); |
3465 } | 3548 } |
3466 | 3549 |
3467 | 3550 |
3468 } // namespace dart | 3551 } // namespace dart |
OLD | NEW |