| 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 |