| 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 27 matching lines...) Expand all Loading... |
| 38 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); | 38 DEFINE_FLAG(bool, print_scopes, false, "Print scopes of local variables."); |
| 39 DEFINE_FLAG(bool, trace_type_check_elimination, false, | 39 DEFINE_FLAG(bool, trace_type_check_elimination, false, |
| 40 "Trace type check elimination at compile time."); | 40 "Trace type check elimination at compile time."); |
| 41 | 41 |
| 42 DECLARE_FLAG(bool, profile_vm); | 42 DECLARE_FLAG(bool, profile_vm); |
| 43 DECLARE_FLAG(bool, support_externalizable_strings); | 43 DECLARE_FLAG(bool, support_externalizable_strings); |
| 44 | 44 |
| 45 // Quick access to the locally defined zone() method. | 45 // Quick access to the locally defined zone() method. |
| 46 #define Z (zone()) | 46 #define Z (zone()) |
| 47 | 47 |
| 48 // Quick access to the locally defined thread() method. |
| 49 #define T (thread()) |
| 50 |
| 48 // Quick synthetic token position. | 51 // Quick synthetic token position. |
| 49 #define ST(token_pos) ((token_pos).ToSynthetic()) | 52 #define ST(token_pos) ((token_pos).ToSynthetic()) |
| 50 | 53 |
| 51 // TODO(srdjan): Allow compiler to add constants as they are encountered in | 54 // TODO(srdjan): Allow compiler to add constants as they are encountered in |
| 52 // the compilation. | 55 // the compilation. |
| 53 const double kCommonDoubleConstants[] = | 56 const double kCommonDoubleConstants[] = |
| 54 {-1.0, -0.5, -0.1, 0.0, 0.1, 0.5, 1.0, 2.0, 4.0, 5.0, | 57 {-1.0, -0.5, -0.1, 0.0, 0.1, 0.5, 1.0, 2.0, 4.0, 5.0, |
| 55 10.0, 20.0, 30.0, 64.0, 255.0, NAN, | 58 10.0, 20.0, 30.0, 64.0, 255.0, NAN, |
| 56 // From dart:math | 59 // From dart:math |
| 57 2.718281828459045, 2.302585092994046, 0.6931471805599453, | 60 2.718281828459045, 2.302585092994046, 0.6931471805599453, |
| (...skipping 1327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1385 | 1388 |
| 1386 ValueGraphVisitor for_right_value(owner()); | 1389 ValueGraphVisitor for_right_value(owner()); |
| 1387 node->right()->Visit(&for_right_value); | 1390 node->right()->Visit(&for_right_value); |
| 1388 Append(for_right_value); | 1391 Append(for_right_value); |
| 1389 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 1392 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
| 1390 | 1393 |
| 1391 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1394 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1392 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); | 1395 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1393 arguments->Add(push_left); | 1396 arguments->Add(push_left); |
| 1394 arguments->Add(push_right); | 1397 arguments->Add(push_right); |
| 1395 const String& name = String::ZoneHandle(Z, Symbols::New(node->TokenName())); | 1398 const String& name = Symbols::Token(node->kind()); |
| 1396 const intptr_t kNumArgsChecked = 2; | 1399 const intptr_t kNumArgsChecked = 2; |
| 1397 InstanceCallInstr* call = new(Z) InstanceCallInstr(node->token_pos(), | 1400 InstanceCallInstr* call = new(Z) InstanceCallInstr(node->token_pos(), |
| 1398 name, | 1401 name, |
| 1399 node->kind(), | 1402 node->kind(), |
| 1400 arguments, | 1403 arguments, |
| 1401 Object::null_array(), | 1404 Object::null_array(), |
| 1402 kNumArgsChecked, | 1405 kNumArgsChecked, |
| 1403 owner()->ic_data_array()); | 1406 owner()->ic_data_array()); |
| 1404 ReturnDefinition(call); | 1407 ReturnDefinition(call); |
| 1405 } | 1408 } |
| (...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1821 | 1824 |
| 1822 ValueGraphVisitor for_right_value(owner()); | 1825 ValueGraphVisitor for_right_value(owner()); |
| 1823 node->right()->Visit(&for_right_value); | 1826 node->right()->Visit(&for_right_value); |
| 1824 Append(for_right_value); | 1827 Append(for_right_value); |
| 1825 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 1828 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
| 1826 arguments->Add(push_right); | 1829 arguments->Add(push_right); |
| 1827 | 1830 |
| 1828 ASSERT(Token::IsRelationalOperator(node->kind())); | 1831 ASSERT(Token::IsRelationalOperator(node->kind())); |
| 1829 InstanceCallInstr* comp = new(Z) InstanceCallInstr( | 1832 InstanceCallInstr* comp = new(Z) InstanceCallInstr( |
| 1830 node->token_pos(), | 1833 node->token_pos(), |
| 1831 String::ZoneHandle(Z, Symbols::New(node->TokenName())), | 1834 Symbols::Token(node->kind()), |
| 1832 node->kind(), | 1835 node->kind(), |
| 1833 arguments, | 1836 arguments, |
| 1834 Object::null_array(), | 1837 Object::null_array(), |
| 1835 2, | 1838 2, |
| 1836 owner()->ic_data_array()); | 1839 owner()->ic_data_array()); |
| 1837 ReturnDefinition(comp); | 1840 ReturnDefinition(comp); |
| 1838 } | 1841 } |
| 1839 | 1842 |
| 1840 | 1843 |
| 1841 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 1844 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1857 | 1860 |
| 1858 ValueGraphVisitor for_value(owner()); | 1861 ValueGraphVisitor for_value(owner()); |
| 1859 node->operand()->Visit(&for_value); | 1862 node->operand()->Visit(&for_value); |
| 1860 Append(for_value); | 1863 Append(for_value); |
| 1861 PushArgumentInstr* push_value = PushArgument(for_value.value()); | 1864 PushArgumentInstr* push_value = PushArgument(for_value.value()); |
| 1862 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1865 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1863 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); | 1866 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); |
| 1864 arguments->Add(push_value); | 1867 arguments->Add(push_value); |
| 1865 InstanceCallInstr* call = new(Z) InstanceCallInstr( | 1868 InstanceCallInstr* call = new(Z) InstanceCallInstr( |
| 1866 node->token_pos(), | 1869 node->token_pos(), |
| 1867 String::ZoneHandle(Z, Symbols::New(node->TokenName())), | 1870 Symbols::Token(node->kind()), |
| 1868 node->kind(), | 1871 node->kind(), |
| 1869 arguments, | 1872 arguments, |
| 1870 Object::null_array(), | 1873 Object::null_array(), |
| 1871 1, | 1874 1, |
| 1872 owner()->ic_data_array()); | 1875 owner()->ic_data_array()); |
| 1873 ReturnDefinition(call); | 1876 ReturnDefinition(call); |
| 1874 } | 1877 } |
| 1875 | 1878 |
| 1876 | 1879 |
| 1877 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 1880 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2294 Value* value, TokenPosition token_pos) { | 2297 Value* value, TokenPosition token_pos) { |
| 2295 Do(new(Z) PushTempInstr(value)); | 2298 Do(new(Z) PushTempInstr(value)); |
| 2296 owner()->AllocateTemp(); | 2299 owner()->AllocateTemp(); |
| 2297 | 2300 |
| 2298 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1)); | 2301 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1)); |
| 2299 intptr_t index = GetCurrentTempLocalIndex(); | 2302 intptr_t index = GetCurrentTempLocalIndex(); |
| 2300 char name[64]; | 2303 char name[64]; |
| 2301 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); | 2304 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); |
| 2302 LocalVariable* var = | 2305 LocalVariable* var = |
| 2303 new(Z) LocalVariable(TokenPosition::kNoSource, | 2306 new(Z) LocalVariable(TokenPosition::kNoSource, |
| 2304 String::ZoneHandle(Z, Symbols::New(name)), | 2307 String::ZoneHandle(Z, Symbols::New(T, name)), |
| 2305 *value->Type()->ToAbstractType()); | 2308 *value->Type()->ToAbstractType()); |
| 2306 var->set_index(index); | 2309 var->set_index(index); |
| 2307 return var; | 2310 return var; |
| 2308 } | 2311 } |
| 2309 | 2312 |
| 2310 | 2313 |
| 2311 Definition* EffectGraphVisitor::ExitTempLocalScope( | 2314 Definition* EffectGraphVisitor::ExitTempLocalScope( |
| 2312 LocalVariable* var, TokenPosition token_pos) { | 2315 LocalVariable* var, TokenPosition token_pos) { |
| 2313 Value* tmp = Bind(new(Z) LoadLocalInstr(*var, token_pos)); | 2316 Value* tmp = Bind(new(Z) LoadLocalInstr(*var, token_pos)); |
| 2314 owner()->DeallocateTemps(1); | 2317 owner()->DeallocateTemps(1); |
| (...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3219 | 3222 |
| 3220 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { | 3223 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { |
| 3221 const String& getter_name = | 3224 const String& getter_name = |
| 3222 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name())); | 3225 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name())); |
| 3223 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 3226 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 3224 new(Z) ZoneGrowableArray<PushArgumentInstr*>(); | 3227 new(Z) ZoneGrowableArray<PushArgumentInstr*>(); |
| 3225 Function& getter_function = Function::ZoneHandle(Z, Function::null()); | 3228 Function& getter_function = Function::ZoneHandle(Z, Function::null()); |
| 3226 if (node->is_super_getter()) { | 3229 if (node->is_super_getter()) { |
| 3227 // Statically resolved instance getter, i.e. "super getter". | 3230 // Statically resolved instance getter, i.e. "super getter". |
| 3228 ASSERT(node->receiver() != NULL); | 3231 ASSERT(node->receiver() != NULL); |
| 3229 getter_function = Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); | 3232 getter_function = Resolver::ResolveDynamicAnyArgs(Z, |
| 3233 node->cls(), getter_name); |
| 3230 if (getter_function.IsNull()) { | 3234 if (getter_function.IsNull()) { |
| 3231 // Resolve and call noSuchMethod. | 3235 // Resolve and call noSuchMethod. |
| 3232 ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos()); | 3236 ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos()); |
| 3233 arguments->Add(node->receiver()); | 3237 arguments->Add(node->receiver()); |
| 3234 StaticCallInstr* call = | 3238 StaticCallInstr* call = |
| 3235 BuildStaticNoSuchMethodCall(node->cls(), | 3239 BuildStaticNoSuchMethodCall(node->cls(), |
| 3236 node->receiver(), | 3240 node->receiver(), |
| 3237 getter_name, | 3241 getter_name, |
| 3238 arguments, | 3242 arguments, |
| 3239 false, // Don't save last argument. | 3243 false, // Don't save last argument. |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3787 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 3791 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 3788 ReturnDefinition( | 3792 ReturnDefinition( |
| 3789 BuildStoreStaticField(node, kResultNeeded, node->token_pos())); | 3793 BuildStoreStaticField(node, kResultNeeded, node->token_pos())); |
| 3790 } | 3794 } |
| 3791 | 3795 |
| 3792 | 3796 |
| 3793 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { | 3797 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 3794 Function* super_function = NULL; | 3798 Function* super_function = NULL; |
| 3795 if (node->IsSuperLoad()) { | 3799 if (node->IsSuperLoad()) { |
| 3796 // Resolve the load indexed operator in the super class. | 3800 // Resolve the load indexed operator in the super class. |
| 3797 super_function = &Function::ZoneHandle( | 3801 super_function = &Function::ZoneHandle(Z, Resolver::ResolveDynamicAnyArgs(Z, |
| 3798 Z, Resolver::ResolveDynamicAnyArgs(node->super_class(), | 3802 node->super_class(), Symbols::IndexToken())); |
| 3799 Symbols::IndexToken())); | |
| 3800 if (super_function->IsNull()) { | 3803 if (super_function->IsNull()) { |
| 3801 // Could not resolve super operator. Generate call noSuchMethod() of the | 3804 // Could not resolve super operator. Generate call noSuchMethod() of the |
| 3802 // super class instead. | 3805 // super class instead. |
| 3803 ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos()); | 3806 ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos()); |
| 3804 arguments->Add(node->array()); | 3807 arguments->Add(node->array()); |
| 3805 arguments->Add(node->index_expr()); | 3808 arguments->Add(node->index_expr()); |
| 3806 StaticCallInstr* call = | 3809 StaticCallInstr* call = |
| 3807 BuildStaticNoSuchMethodCall(node->super_class(), | 3810 BuildStaticNoSuchMethodCall(node->super_class(), |
| 3808 node->array(), | 3811 node->array(), |
| 3809 Symbols::IndexToken(), | 3812 Symbols::IndexToken(), |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3850 } | 3853 } |
| 3851 | 3854 |
| 3852 | 3855 |
| 3853 Definition* EffectGraphVisitor::BuildStoreIndexedValues( | 3856 Definition* EffectGraphVisitor::BuildStoreIndexedValues( |
| 3854 StoreIndexedNode* node, | 3857 StoreIndexedNode* node, |
| 3855 bool result_is_needed) { | 3858 bool result_is_needed) { |
| 3856 Function* super_function = NULL; | 3859 Function* super_function = NULL; |
| 3857 const TokenPosition token_pos = node->token_pos(); | 3860 const TokenPosition token_pos = node->token_pos(); |
| 3858 if (node->IsSuperStore()) { | 3861 if (node->IsSuperStore()) { |
| 3859 // Resolve the store indexed operator in the super class. | 3862 // Resolve the store indexed operator in the super class. |
| 3860 super_function = &Function::ZoneHandle( | 3863 super_function = &Function::ZoneHandle(Z, Resolver::ResolveDynamicAnyArgs(Z, |
| 3861 Z, Resolver::ResolveDynamicAnyArgs(node->super_class(), | 3864 node->super_class(), Symbols::AssignIndexToken())); |
| 3862 Symbols::AssignIndexToken())); | |
| 3863 if (super_function->IsNull()) { | 3865 if (super_function->IsNull()) { |
| 3864 // Could not resolve super operator. Generate call noSuchMethod() of the | 3866 // Could not resolve super operator. Generate call noSuchMethod() of the |
| 3865 // super class instead. | 3867 // super class instead. |
| 3866 ArgumentListNode* arguments = new(Z) ArgumentListNode(token_pos); | 3868 ArgumentListNode* arguments = new(Z) ArgumentListNode(token_pos); |
| 3867 arguments->Add(node->array()); | 3869 arguments->Add(node->array()); |
| 3868 arguments->Add(node->index_expr()); | 3870 arguments->Add(node->index_expr()); |
| 3869 arguments->Add(node->value()); | 3871 arguments->Add(node->value()); |
| 3870 StaticCallInstr* call = BuildStaticNoSuchMethodCall( | 3872 StaticCallInstr* call = BuildStaticNoSuchMethodCall( |
| 3871 node->super_class(), | 3873 node->super_class(), |
| 3872 node->array(), | 3874 node->array(), |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3918 owner()->ic_data_array()); | 3920 owner()->ic_data_array()); |
| 3919 if (result_is_needed) { | 3921 if (result_is_needed) { |
| 3920 Do(store); | 3922 Do(store); |
| 3921 return BuildLoadExprTemp(token_pos); | 3923 return BuildLoadExprTemp(token_pos); |
| 3922 } else { | 3924 } else { |
| 3923 return store; | 3925 return store; |
| 3924 } | 3926 } |
| 3925 } else { | 3927 } else { |
| 3926 // Generate dynamic call to operator []=. | 3928 // Generate dynamic call to operator []=. |
| 3927 const intptr_t checked_argument_count = 2; // Do not check for value type. | 3929 const intptr_t checked_argument_count = 2; // Do not check for value type. |
| 3928 const String& name = | |
| 3929 String::ZoneHandle(Z, Symbols::New(Token::Str(Token::kASSIGN_INDEX))); | |
| 3930 InstanceCallInstr* store = | 3930 InstanceCallInstr* store = |
| 3931 new(Z) InstanceCallInstr(token_pos, | 3931 new(Z) InstanceCallInstr(token_pos, |
| 3932 name, | 3932 Symbols::AssignIndexToken(), |
| 3933 Token::kASSIGN_INDEX, | 3933 Token::kASSIGN_INDEX, |
| 3934 arguments, | 3934 arguments, |
| 3935 Object::null_array(), | 3935 Object::null_array(), |
| 3936 checked_argument_count, | 3936 checked_argument_count, |
| 3937 owner()->ic_data_array()); | 3937 owner()->ic_data_array()); |
| 3938 if (result_is_needed) { | 3938 if (result_is_needed) { |
| 3939 Do(store); | 3939 Do(store); |
| 3940 return BuildLoadExprTemp(token_pos); | 3940 return BuildLoadExprTemp(token_pos); |
| 3941 } else { | 3941 } else { |
| 3942 return store; | 3942 return store; |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4467 Type::New(function_class, | 4467 Type::New(function_class, |
| 4468 TypeArguments::Handle(Z, TypeArguments::null()), | 4468 TypeArguments::Handle(Z, TypeArguments::null()), |
| 4469 token_pos, | 4469 token_pos, |
| 4470 Heap::kOld)); | 4470 Heap::kOld)); |
| 4471 type ^= ClassFinalizer::FinalizeType( | 4471 type ^= ClassFinalizer::FinalizeType( |
| 4472 function_class, type, ClassFinalizer::kCanonicalize); | 4472 function_class, type, ClassFinalizer::kCanonicalize); |
| 4473 Value* receiver_value = Bind(new(Z) ConstantInstr(type)); | 4473 Value* receiver_value = Bind(new(Z) ConstantInstr(type)); |
| 4474 arguments->Add(PushArgument(receiver_value)); | 4474 arguments->Add(PushArgument(receiver_value)); |
| 4475 // String memberName. | 4475 // String memberName. |
| 4476 const String& member_name = | 4476 const String& member_name = |
| 4477 String::ZoneHandle(Z, Symbols::New(function_name)); | 4477 String::ZoneHandle(Z, Symbols::New(T, function_name)); |
| 4478 Value* member_name_value = Bind(new(Z) ConstantInstr(member_name)); | 4478 Value* member_name_value = Bind(new(Z) ConstantInstr(member_name)); |
| 4479 arguments->Add(PushArgument(member_name_value)); | 4479 arguments->Add(PushArgument(member_name_value)); |
| 4480 // Smi invocation_type. | 4480 // Smi invocation_type. |
| 4481 Value* invocation_type_value = Bind(new(Z) ConstantInstr( | 4481 Value* invocation_type_value = Bind(new(Z) ConstantInstr( |
| 4482 Smi::ZoneHandle(Z, Smi::New(invocation_type)))); | 4482 Smi::ZoneHandle(Z, Smi::New(invocation_type)))); |
| 4483 arguments->Add(PushArgument(invocation_type_value)); | 4483 arguments->Add(PushArgument(invocation_type_value)); |
| 4484 // List arguments. | 4484 // List arguments. |
| 4485 if (function_arguments == NULL) { | 4485 if (function_arguments == NULL) { |
| 4486 Value* arguments_value = Bind( | 4486 Value* arguments_value = Bind( |
| 4487 new(Z) ConstantInstr(Array::ZoneHandle(Z, Array::null()))); | 4487 new(Z) ConstantInstr(Array::ZoneHandle(Z, Array::null()))); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4664 Script::Handle(function.script()), | 4664 Script::Handle(function.script()), |
| 4665 function.token_pos(), | 4665 function.token_pos(), |
| 4666 Report::AtLocation, | 4666 Report::AtLocation, |
| 4667 "FlowGraphBuilder Bailout: %s %s", | 4667 "FlowGraphBuilder Bailout: %s %s", |
| 4668 String::Handle(function.name()).ToCString(), | 4668 String::Handle(function.name()).ToCString(), |
| 4669 reason); | 4669 reason); |
| 4670 UNREACHABLE(); | 4670 UNREACHABLE(); |
| 4671 } | 4671 } |
| 4672 | 4672 |
| 4673 } // namespace dart | 4673 } // namespace dart |
| OLD | NEW |