| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 "Trace type check elimination at compile time."); | 39 "Trace type check elimination at compile time."); |
| 40 DEFINE_FLAG(bool, warn_on_javascript_compatibility, false, | 40 DEFINE_FLAG(bool, warn_on_javascript_compatibility, false, |
| 41 "Warn on incompatibilities between vm and dart2js."); | 41 "Warn on incompatibilities between vm and dart2js."); |
| 42 | 42 |
| 43 DECLARE_FLAG(bool, enable_debugger); | 43 DECLARE_FLAG(bool, enable_debugger); |
| 44 DECLARE_FLAG(bool, enable_type_checks); | 44 DECLARE_FLAG(bool, enable_type_checks); |
| 45 DECLARE_FLAG(int, optimization_counter_threshold); | 45 DECLARE_FLAG(int, optimization_counter_threshold); |
| 46 DECLARE_FLAG(bool, silent_warnings); | 46 DECLARE_FLAG(bool, silent_warnings); |
| 47 DECLARE_FLAG(bool, warning_as_error); | 47 DECLARE_FLAG(bool, warning_as_error); |
| 48 | 48 |
| 49 // Quick access to the locally defined isolate() method. |
| 50 #define I (isolate()) |
| 49 | 51 |
| 50 // TODO(srdjan): Allow compiler to add constants as they are encountered in | 52 // TODO(srdjan): Allow compiler to add constants as they are encountered in |
| 51 // the compilation. | 53 // the compilation. |
| 52 const double kCommonDoubleConstants[] = | 54 const double kCommonDoubleConstants[] = |
| 53 {-1.0, -0.5, -0.1, 0.0, 0.1, 0.5, 1.0, 2.0, 4.0, 5.0, | 55 {-1.0, -0.5, -0.1, 0.0, 0.1, 0.5, 1.0, 2.0, 4.0, 5.0, |
| 54 10.0, 20.0, 30.0, 64.0, 255.0, NAN, | 56 10.0, 20.0, 30.0, 64.0, 255.0, NAN, |
| 55 // From dart:math | 57 // From dart:math |
| 56 2.718281828459045, 2.302585092994046, 0.6931471805599453, | 58 2.718281828459045, 2.302585092994046, 0.6931471805599453, |
| 57 1.4426950408889634, 0.4342944819032518, 3.1415926535897932, | 59 1.4426950408889634, 0.4342944819032518, 3.1415926535897932, |
| 58 0.7071067811865476, 1.4142135623730951}; | 60 0.7071067811865476, 1.4142135623730951}; |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 739 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, | 741 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, |
| 740 Value* value) { | 742 Value* value) { |
| 741 if (local.is_captured()) { | 743 if (local.is_captured()) { |
| 742 LocalVariable* tmp_var = EnterTempLocalScope(value); | 744 LocalVariable* tmp_var = EnterTempLocalScope(value); |
| 743 intptr_t delta = | 745 intptr_t delta = |
| 744 owner()->context_level() - local.owner()->context_level(); | 746 owner()->context_level() - local.owner()->context_level(); |
| 745 ASSERT(delta >= 0); | 747 ASSERT(delta >= 0); |
| 746 Value* context = Bind(new CurrentContextInstr()); | 748 Value* context = Bind(new CurrentContextInstr()); |
| 747 while (delta-- > 0) { | 749 while (delta-- > 0) { |
| 748 context = Bind(new LoadFieldInstr( | 750 context = Bind(new LoadFieldInstr( |
| 749 context, Context::parent_offset(), Type::ZoneHandle(), | 751 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), |
| 750 Scanner::kNoSourcePos)); | 752 Scanner::kNoSourcePos)); |
| 751 } | 753 } |
| 752 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var)); | 754 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var)); |
| 753 StoreInstanceFieldInstr* store = | 755 StoreInstanceFieldInstr* store = |
| 754 new StoreInstanceFieldInstr(Context::variable_offset(local.index()), | 756 new StoreInstanceFieldInstr(Context::variable_offset(local.index()), |
| 755 context, | 757 context, |
| 756 tmp_val, | 758 tmp_val, |
| 757 kEmitStoreBarrier, | 759 kEmitStoreBarrier, |
| 758 Scanner::kNoSourcePos); | 760 Scanner::kNoSourcePos); |
| 759 Do(store); | 761 Do(store); |
| 760 return ExitTempLocalScope(tmp_var); | 762 return ExitTempLocalScope(tmp_var); |
| 761 } else { | 763 } else { |
| 762 return new StoreLocalInstr(local, value); | 764 return new StoreLocalInstr(local, value); |
| 763 } | 765 } |
| 764 } | 766 } |
| 765 | 767 |
| 766 | 768 |
| 767 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { | 769 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { |
| 768 if (local.IsConst()) { | 770 if (local.IsConst()) { |
| 769 return new ConstantInstr(*local.ConstValue()); | 771 return new ConstantInstr(*local.ConstValue()); |
| 770 } else if (local.is_captured()) { | 772 } else if (local.is_captured()) { |
| 771 intptr_t delta = | 773 intptr_t delta = |
| 772 owner()->context_level() - local.owner()->context_level(); | 774 owner()->context_level() - local.owner()->context_level(); |
| 773 ASSERT(delta >= 0); | 775 ASSERT(delta >= 0); |
| 774 Value* context = Bind(new CurrentContextInstr()); | 776 Value* context = Bind(new CurrentContextInstr()); |
| 775 while (delta-- > 0) { | 777 while (delta-- > 0) { |
| 776 context = Bind(new LoadFieldInstr( | 778 context = Bind(new LoadFieldInstr( |
| 777 context, Context::parent_offset(), Type::ZoneHandle(), | 779 context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()), |
| 778 Scanner::kNoSourcePos)); | 780 Scanner::kNoSourcePos)); |
| 779 } | 781 } |
| 780 return new LoadFieldInstr(context, | 782 return new LoadFieldInstr(context, |
| 781 Context::variable_offset(local.index()), | 783 Context::variable_offset(local.index()), |
| 782 local.type(), | 784 local.type(), |
| 783 Scanner::kNoSourcePos); | 785 Scanner::kNoSourcePos); |
| 784 } else { | 786 } else { |
| 785 return new LoadLocalInstr(local); | 787 return new LoadLocalInstr(local); |
| 786 } | 788 } |
| 787 } | 789 } |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1014 (!function.is_static() && | 1016 (!function.is_static() && |
| 1015 ((function.kind() == RawFunction::kImplicitGetter) || | 1017 ((function.kind() == RawFunction::kImplicitGetter) || |
| 1016 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); | 1018 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); |
| 1017 // Implicit getters do not need a type check at return, unless they compute | 1019 // Implicit getters do not need a type check at return, unless they compute |
| 1018 // the initial value of a static field. | 1020 // the initial value of a static field. |
| 1019 // The body of a constructor cannot modify the type of the | 1021 // The body of a constructor cannot modify the type of the |
| 1020 // constructed instance, which is passed in as an implicit parameter. | 1022 // constructed instance, which is passed in as an implicit parameter. |
| 1021 // However, factories may create an instance of the wrong type. | 1023 // However, factories may create an instance of the wrong type. |
| 1022 if (!is_implicit_dynamic_getter && !function.IsConstructor()) { | 1024 if (!is_implicit_dynamic_getter && !function.IsConstructor()) { |
| 1023 const AbstractType& dst_type = | 1025 const AbstractType& dst_type = |
| 1024 AbstractType::ZoneHandle(function.result_type()); | 1026 AbstractType::ZoneHandle(I, function.result_type()); |
| 1025 return_value = BuildAssignableValue(node->value()->token_pos(), | 1027 return_value = BuildAssignableValue(node->value()->token_pos(), |
| 1026 return_value, | 1028 return_value, |
| 1027 dst_type, | 1029 dst_type, |
| 1028 Symbols::FunctionResult()); | 1030 Symbols::FunctionResult()); |
| 1029 } | 1031 } |
| 1030 } | 1032 } |
| 1031 | 1033 |
| 1032 intptr_t current_context_level = owner()->context_level(); | 1034 intptr_t current_context_level = owner()->context_level(); |
| 1033 ASSERT(current_context_level >= 0); | 1035 ASSERT(current_context_level >= 0); |
| 1034 if (owner()->parsed_function()->saved_entry_context_var() != NULL) { | 1036 if (owner()->parsed_function()->saved_entry_context_var() != NULL) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1057 | 1059 |
| 1058 | 1060 |
| 1059 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) { | 1061 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) { |
| 1060 const AbstractType& type = node->type(); | 1062 const AbstractType& type = node->type(); |
| 1061 // Type may be malbounded, but not malformed. | 1063 // Type may be malbounded, but not malformed. |
| 1062 ASSERT(type.IsFinalized() && !type.IsMalformed()); | 1064 ASSERT(type.IsFinalized() && !type.IsMalformed()); |
| 1063 if (type.IsInstantiated()) { | 1065 if (type.IsInstantiated()) { |
| 1064 ReturnDefinition(new ConstantInstr(type)); | 1066 ReturnDefinition(new ConstantInstr(type)); |
| 1065 } else { | 1067 } else { |
| 1066 const Class& instantiator_class = Class::ZoneHandle( | 1068 const Class& instantiator_class = Class::ZoneHandle( |
| 1067 owner()->parsed_function()->function().Owner()); | 1069 I, owner()->parsed_function()->function().Owner()); |
| 1068 Value* instantiator_value = BuildInstantiatorTypeArguments( | 1070 Value* instantiator_value = BuildInstantiatorTypeArguments( |
| 1069 node->token_pos(), instantiator_class, NULL); | 1071 node->token_pos(), instantiator_class, NULL); |
| 1070 ReturnDefinition(new InstantiateTypeInstr( | 1072 ReturnDefinition(new InstantiateTypeInstr( |
| 1071 node->token_pos(), type, instantiator_class, instantiator_value)); | 1073 node->token_pos(), type, instantiator_class, instantiator_value)); |
| 1072 } | 1074 } |
| 1073 } | 1075 } |
| 1074 | 1076 |
| 1075 | 1077 |
| 1076 // Returns true if the type check can be skipped, for example, if the | 1078 // Returns true if the type check can be skipped, for example, if the |
| 1077 // destination type is dynamic or if the compile type of the value is a subtype | 1079 // destination type is dynamic or if the compile type of the value is a subtype |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1194 | 1196 |
| 1195 ValueGraphVisitor for_right_value(owner()); | 1197 ValueGraphVisitor for_right_value(owner()); |
| 1196 node->right()->Visit(&for_right_value); | 1198 node->right()->Visit(&for_right_value); |
| 1197 Append(for_right_value); | 1199 Append(for_right_value); |
| 1198 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 1200 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
| 1199 | 1201 |
| 1200 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1202 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1201 new ZoneGrowableArray<PushArgumentInstr*>(2); | 1203 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1202 arguments->Add(push_left); | 1204 arguments->Add(push_left); |
| 1203 arguments->Add(push_right); | 1205 arguments->Add(push_right); |
| 1204 const String& name = String::ZoneHandle(Symbols::New(node->TokenName())); | 1206 const String& name = String::ZoneHandle(I, Symbols::New(node->TokenName())); |
| 1205 const intptr_t kNumArgsChecked = 2; | 1207 const intptr_t kNumArgsChecked = 2; |
| 1206 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), | 1208 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), |
| 1207 name, | 1209 name, |
| 1208 node->kind(), | 1210 node->kind(), |
| 1209 arguments, | 1211 arguments, |
| 1210 Object::null_array(), | 1212 Object::null_array(), |
| 1211 kNumArgsChecked, | 1213 kNumArgsChecked, |
| 1212 owner()->ic_data_array()); | 1214 owner()->ic_data_array()); |
| 1213 ReturnDefinition(call); | 1215 ReturnDefinition(call); |
| 1214 } | 1216 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1261 } | 1263 } |
| 1262 EffectGraphVisitor::VisitBinaryOpNode(node); | 1264 EffectGraphVisitor::VisitBinaryOpNode(node); |
| 1263 } | 1265 } |
| 1264 | 1266 |
| 1265 | 1267 |
| 1266 static const String& BinaryOpAndMaskName(BinaryOpNode* node) { | 1268 static const String& BinaryOpAndMaskName(BinaryOpNode* node) { |
| 1267 if (node->kind() == Token::kSHL) { | 1269 if (node->kind() == Token::kSHL) { |
| 1268 return Library::PrivateCoreLibName(Symbols::_leftShiftWithMask32()); | 1270 return Library::PrivateCoreLibName(Symbols::_leftShiftWithMask32()); |
| 1269 } | 1271 } |
| 1270 UNIMPLEMENTED(); | 1272 UNIMPLEMENTED(); |
| 1271 return String::ZoneHandle(); | 1273 return String::ZoneHandle(Isolate::Current(), String::null()); |
| 1272 } | 1274 } |
| 1273 | 1275 |
| 1274 | 1276 |
| 1275 // <Expression> :: BinaryOp { kind: Token::Kind | 1277 // <Expression> :: BinaryOp { kind: Token::Kind |
| 1276 // left: <Expression> | 1278 // left: <Expression> |
| 1277 // right: <Expression> | 1279 // right: <Expression> |
| 1278 // mask32: constant } | 1280 // mask32: constant } |
| 1279 void EffectGraphVisitor::VisitBinaryOpWithMask32Node( | 1281 void EffectGraphVisitor::VisitBinaryOpWithMask32Node( |
| 1280 BinaryOpWithMask32Node* node) { | 1282 BinaryOpWithMask32Node* node) { |
| 1281 ASSERT((node->kind() != Token::kAND) && (node->kind() != Token::kOR)); | 1283 ASSERT((node->kind() != Token::kAND) && (node->kind() != Token::kOR)); |
| 1282 ValueGraphVisitor for_left_value(owner()); | 1284 ValueGraphVisitor for_left_value(owner()); |
| 1283 node->left()->Visit(&for_left_value); | 1285 node->left()->Visit(&for_left_value); |
| 1284 Append(for_left_value); | 1286 Append(for_left_value); |
| 1285 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 1287 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
| 1286 | 1288 |
| 1287 ValueGraphVisitor for_right_value(owner()); | 1289 ValueGraphVisitor for_right_value(owner()); |
| 1288 node->right()->Visit(&for_right_value); | 1290 node->right()->Visit(&for_right_value); |
| 1289 Append(for_right_value); | 1291 Append(for_right_value); |
| 1290 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 1292 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
| 1291 | 1293 |
| 1292 Value* mask_value = Bind(new ConstantInstr( | 1294 Value* mask_value = Bind(new ConstantInstr( |
| 1293 Integer::ZoneHandle(Integer::New(node->mask32(), Heap::kOld)))); | 1295 Integer::ZoneHandle(I, Integer::New(node->mask32(), Heap::kOld)))); |
| 1294 PushArgumentInstr* push_mask = PushArgument(mask_value); | 1296 PushArgumentInstr* push_mask = PushArgument(mask_value); |
| 1295 | 1297 |
| 1296 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1298 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1297 new ZoneGrowableArray<PushArgumentInstr*>(3); | 1299 new ZoneGrowableArray<PushArgumentInstr*>(3); |
| 1298 arguments->Add(push_left); | 1300 arguments->Add(push_left); |
| 1299 arguments->Add(push_right); | 1301 arguments->Add(push_right); |
| 1300 // Call to special method 'BinaryOpAndMaskName(node)'. | 1302 // Call to special method 'BinaryOpAndMaskName(node)'. |
| 1301 arguments->Add(push_mask); | 1303 arguments->Add(push_mask); |
| 1302 const intptr_t kNumArgsChecked = 2; | 1304 const intptr_t kNumArgsChecked = 2; |
| 1303 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), | 1305 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), |
| 1304 BinaryOpAndMaskName(node), | 1306 BinaryOpAndMaskName(node), |
| 1305 Token::kILLEGAL, | 1307 Token::kILLEGAL, |
| 1306 arguments, | 1308 arguments, |
| 1307 Object::null_array(), | 1309 Object::null_array(), |
| 1308 kNumArgsChecked, | 1310 kNumArgsChecked, |
| 1309 owner()->ic_data_array()); | 1311 owner()->ic_data_array()); |
| 1310 ReturnDefinition(call); | 1312 ReturnDefinition(call); |
| 1311 } | 1313 } |
| 1312 | 1314 |
| 1313 | 1315 |
| 1314 void EffectGraphVisitor::BuildTypecheckPushArguments( | 1316 void EffectGraphVisitor::BuildTypecheckPushArguments( |
| 1315 intptr_t token_pos, | 1317 intptr_t token_pos, |
| 1316 PushArgumentInstr** push_instantiator_result, | 1318 PushArgumentInstr** push_instantiator_result, |
| 1317 PushArgumentInstr** push_instantiator_type_arguments_result) { | 1319 PushArgumentInstr** push_instantiator_type_arguments_result) { |
| 1318 const Class& instantiator_class = Class::Handle( | 1320 const Class& instantiator_class = Class::Handle( |
| 1319 owner()->parsed_function()->function().Owner()); | 1321 I, owner()->parsed_function()->function().Owner()); |
| 1320 // Since called only when type tested against is not instantiated. | 1322 // Since called only when type tested against is not instantiated. |
| 1321 ASSERT(instantiator_class.NumTypeParameters() > 0); | 1323 ASSERT(instantiator_class.NumTypeParameters() > 0); |
| 1322 Value* instantiator_type_arguments = NULL; | 1324 Value* instantiator_type_arguments = NULL; |
| 1323 Value* instantiator = BuildInstantiator(instantiator_class); | 1325 Value* instantiator = BuildInstantiator(instantiator_class); |
| 1324 if (instantiator == NULL) { | 1326 if (instantiator == NULL) { |
| 1325 // No instantiator when inside factory. | 1327 // No instantiator when inside factory. |
| 1326 *push_instantiator_result = PushArgument(BuildNullValue()); | 1328 *push_instantiator_result = PushArgument(BuildNullValue()); |
| 1327 instantiator_type_arguments = | 1329 instantiator_type_arguments = |
| 1328 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1330 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 1329 } else { | 1331 } else { |
| 1330 instantiator = Bind(BuildStoreExprTemp(instantiator)); | 1332 instantiator = Bind(BuildStoreExprTemp(instantiator)); |
| 1331 *push_instantiator_result = PushArgument(instantiator); | 1333 *push_instantiator_result = PushArgument(instantiator); |
| 1332 Value* loaded = Bind(BuildLoadExprTemp()); | 1334 Value* loaded = Bind(BuildLoadExprTemp()); |
| 1333 instantiator_type_arguments = | 1335 instantiator_type_arguments = |
| 1334 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded); | 1336 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded); |
| 1335 } | 1337 } |
| 1336 *push_instantiator_type_arguments_result = | 1338 *push_instantiator_type_arguments_result = |
| 1337 PushArgument(instantiator_type_arguments); | 1339 PushArgument(instantiator_type_arguments); |
| 1338 } | 1340 } |
| 1339 | 1341 |
| 1340 | 1342 |
| 1341 | 1343 |
| 1342 void EffectGraphVisitor::BuildTypecheckArguments( | 1344 void EffectGraphVisitor::BuildTypecheckArguments( |
| 1343 intptr_t token_pos, | 1345 intptr_t token_pos, |
| 1344 Value** instantiator_result, | 1346 Value** instantiator_result, |
| 1345 Value** instantiator_type_arguments_result) { | 1347 Value** instantiator_type_arguments_result) { |
| 1346 Value* instantiator = NULL; | 1348 Value* instantiator = NULL; |
| 1347 Value* instantiator_type_arguments = NULL; | 1349 Value* instantiator_type_arguments = NULL; |
| 1348 const Class& instantiator_class = Class::Handle( | 1350 const Class& instantiator_class = Class::Handle( |
| 1349 owner()->parsed_function()->function().Owner()); | 1351 I, owner()->parsed_function()->function().Owner()); |
| 1350 // Since called only when type tested against is not instantiated. | 1352 // Since called only when type tested against is not instantiated. |
| 1351 ASSERT(instantiator_class.NumTypeParameters() > 0); | 1353 ASSERT(instantiator_class.NumTypeParameters() > 0); |
| 1352 instantiator = BuildInstantiator(instantiator_class); | 1354 instantiator = BuildInstantiator(instantiator_class); |
| 1353 if (instantiator == NULL) { | 1355 if (instantiator == NULL) { |
| 1354 // No instantiator when inside factory. | 1356 // No instantiator when inside factory. |
| 1355 instantiator = BuildNullValue(); | 1357 instantiator = BuildNullValue(); |
| 1356 instantiator_type_arguments = | 1358 instantiator_type_arguments = |
| 1357 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1359 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 1358 } else { | 1360 } else { |
| 1359 // Preserve instantiator. | 1361 // Preserve instantiator. |
| 1360 instantiator = Bind(BuildStoreExprTemp(instantiator)); | 1362 instantiator = Bind(BuildStoreExprTemp(instantiator)); |
| 1361 Value* loaded = Bind(BuildLoadExprTemp()); | 1363 Value* loaded = Bind(BuildLoadExprTemp()); |
| 1362 instantiator_type_arguments = | 1364 instantiator_type_arguments = |
| 1363 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded); | 1365 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded); |
| 1364 } | 1366 } |
| 1365 *instantiator_result = instantiator; | 1367 *instantiator_result = instantiator; |
| 1366 *instantiator_type_arguments_result = instantiator_type_arguments; | 1368 *instantiator_type_arguments_result = instantiator_type_arguments; |
| 1367 } | 1369 } |
| 1368 | 1370 |
| 1369 | 1371 |
| 1370 Value* EffectGraphVisitor::BuildNullValue() { | 1372 Value* EffectGraphVisitor::BuildNullValue() { |
| 1371 return Bind(new ConstantInstr(Object::ZoneHandle())); | 1373 return Bind(new ConstantInstr(Object::ZoneHandle(I, Object::null()))); |
| 1372 } | 1374 } |
| 1373 | 1375 |
| 1374 | 1376 |
| 1375 // Used for testing incoming arguments. | 1377 // Used for testing incoming arguments. |
| 1376 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( | 1378 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( |
| 1377 intptr_t token_pos, | 1379 intptr_t token_pos, |
| 1378 Value* value, | 1380 Value* value, |
| 1379 const AbstractType& dst_type, | 1381 const AbstractType& dst_type, |
| 1380 const String& dst_name) { | 1382 const String& dst_name) { |
| 1381 // Build the type check computation. | 1383 // Build the type check computation. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1442 } | 1444 } |
| 1443 } | 1445 } |
| 1444 | 1446 |
| 1445 | 1447 |
| 1446 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { | 1448 void EffectGraphVisitor::BuildTypeTest(ComparisonNode* node) { |
| 1447 ASSERT(Token::IsTypeTestOperator(node->kind())); | 1449 ASSERT(Token::IsTypeTestOperator(node->kind())); |
| 1448 const AbstractType& type = node->right()->AsTypeNode()->type(); | 1450 const AbstractType& type = node->right()->AsTypeNode()->type(); |
| 1449 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); | 1451 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); |
| 1450 const bool negate_result = (node->kind() == Token::kISNOT); | 1452 const bool negate_result = (node->kind() == Token::kISNOT); |
| 1451 // All objects are instances of type T if Object type is a subtype of type T. | 1453 // All objects are instances of type T if Object type is a subtype of type T. |
| 1452 const Type& object_type = Type::Handle(Type::ObjectType()); | 1454 const Type& object_type = Type::Handle(I, Type::ObjectType()); |
| 1453 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { | 1455 if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) { |
| 1454 // Must evaluate left side. | 1456 // Must evaluate left side. |
| 1455 EffectGraphVisitor for_left_value(owner()); | 1457 EffectGraphVisitor for_left_value(owner()); |
| 1456 node->left()->Visit(&for_left_value); | 1458 node->left()->Visit(&for_left_value); |
| 1457 Append(for_left_value); | 1459 Append(for_left_value); |
| 1458 ReturnDefinition(new ConstantInstr(Bool::Get(!negate_result))); | 1460 ReturnDefinition(new ConstantInstr(Bool::Get(!negate_result))); |
| 1459 return; | 1461 return; |
| 1460 } | 1462 } |
| 1461 | 1463 |
| 1462 // Check for javascript compatibility. | 1464 // Check for javascript compatibility. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1511 | 1513 |
| 1512 // Check for javascript compatibility. | 1514 // Check for javascript compatibility. |
| 1513 if (FLAG_warn_on_javascript_compatibility) { | 1515 if (FLAG_warn_on_javascript_compatibility) { |
| 1514 owner()->WarnOnJSIntegralNumTypeTest(node->left(), type); | 1516 owner()->WarnOnJSIntegralNumTypeTest(node->left(), type); |
| 1515 } | 1517 } |
| 1516 | 1518 |
| 1517 ValueGraphVisitor for_value(owner()); | 1519 ValueGraphVisitor for_value(owner()); |
| 1518 node->left()->Visit(&for_value); | 1520 node->left()->Visit(&for_value); |
| 1519 Append(for_value); | 1521 Append(for_value); |
| 1520 const String& dst_name = String::ZoneHandle( | 1522 const String& dst_name = String::ZoneHandle( |
| 1521 Symbols::New(Exceptions::kCastErrorDstName)); | 1523 I, Symbols::New(Exceptions::kCastErrorDstName)); |
| 1522 if (CanSkipTypeCheck(node->token_pos(), | 1524 if (CanSkipTypeCheck(node->token_pos(), |
| 1523 for_value.value(), | 1525 for_value.value(), |
| 1524 type, | 1526 type, |
| 1525 dst_name)) { | 1527 dst_name)) { |
| 1526 ReturnValue(for_value.value()); | 1528 ReturnValue(for_value.value()); |
| 1527 return; | 1529 return; |
| 1528 } | 1530 } |
| 1529 PushArgumentInstr* push_left = PushArgument(for_value.value()); | 1531 PushArgumentInstr* push_left = PushArgument(for_value.value()); |
| 1530 PushArgumentInstr* push_instantiator = NULL; | 1532 PushArgumentInstr* push_instantiator = NULL; |
| 1531 PushArgumentInstr* push_type_args = NULL; | 1533 PushArgumentInstr* push_type_args = NULL; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1658 | 1660 |
| 1659 ValueGraphVisitor for_right_value(owner()); | 1661 ValueGraphVisitor for_right_value(owner()); |
| 1660 node->right()->Visit(&for_right_value); | 1662 node->right()->Visit(&for_right_value); |
| 1661 Append(for_right_value); | 1663 Append(for_right_value); |
| 1662 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); | 1664 PushArgumentInstr* push_right = PushArgument(for_right_value.value()); |
| 1663 arguments->Add(push_right); | 1665 arguments->Add(push_right); |
| 1664 | 1666 |
| 1665 ASSERT(Token::IsRelationalOperator(node->kind())); | 1667 ASSERT(Token::IsRelationalOperator(node->kind())); |
| 1666 InstanceCallInstr* comp = | 1668 InstanceCallInstr* comp = |
| 1667 new InstanceCallInstr(node->token_pos(), | 1669 new InstanceCallInstr(node->token_pos(), |
| 1668 String::ZoneHandle(Symbols::New(node->TokenName())), | 1670 String::ZoneHandle( |
| 1671 I, Symbols::New(node->TokenName())), |
| 1669 node->kind(), | 1672 node->kind(), |
| 1670 arguments, | 1673 arguments, |
| 1671 Object::null_array(), | 1674 Object::null_array(), |
| 1672 2, | 1675 2, |
| 1673 owner()->ic_data_array()); | 1676 owner()->ic_data_array()); |
| 1674 ReturnDefinition(comp); | 1677 ReturnDefinition(comp); |
| 1675 } | 1678 } |
| 1676 | 1679 |
| 1677 | 1680 |
| 1678 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { | 1681 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1693 | 1696 |
| 1694 ValueGraphVisitor for_value(owner()); | 1697 ValueGraphVisitor for_value(owner()); |
| 1695 node->operand()->Visit(&for_value); | 1698 node->operand()->Visit(&for_value); |
| 1696 Append(for_value); | 1699 Append(for_value); |
| 1697 PushArgumentInstr* push_value = PushArgument(for_value.value()); | 1700 PushArgumentInstr* push_value = PushArgument(for_value.value()); |
| 1698 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1701 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1699 new ZoneGrowableArray<PushArgumentInstr*>(1); | 1702 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 1700 arguments->Add(push_value); | 1703 arguments->Add(push_value); |
| 1701 InstanceCallInstr* call = | 1704 InstanceCallInstr* call = |
| 1702 new InstanceCallInstr(node->token_pos(), | 1705 new InstanceCallInstr(node->token_pos(), |
| 1703 String::ZoneHandle(Symbols::New(node->TokenName())), | 1706 String::ZoneHandle( |
| 1707 I, Symbols::New(node->TokenName())), |
| 1704 node->kind(), | 1708 node->kind(), |
| 1705 arguments, | 1709 arguments, |
| 1706 Object::null_array(), | 1710 Object::null_array(), |
| 1707 1, | 1711 1, |
| 1708 owner()->ic_data_array()); | 1712 owner()->ic_data_array()); |
| 1709 ReturnDefinition(call); | 1713 ReturnDefinition(call); |
| 1710 } | 1714 } |
| 1711 | 1715 |
| 1712 | 1716 |
| 1713 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 1717 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2094 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) { | 2098 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) { |
| 2095 Do(new PushTempInstr(value)); | 2099 Do(new PushTempInstr(value)); |
| 2096 owner()->AllocateTemp(); | 2100 owner()->AllocateTemp(); |
| 2097 | 2101 |
| 2098 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1)); | 2102 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1)); |
| 2099 intptr_t index = GetCurrentTempLocalIndex(); | 2103 intptr_t index = GetCurrentTempLocalIndex(); |
| 2100 char name[64]; | 2104 char name[64]; |
| 2101 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); | 2105 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); |
| 2102 LocalVariable* var = | 2106 LocalVariable* var = |
| 2103 new LocalVariable(0, | 2107 new LocalVariable(0, |
| 2104 String::ZoneHandle(Symbols::New(name)), | 2108 String::ZoneHandle(I, Symbols::New(name)), |
| 2105 *value->Type()->ToAbstractType()); | 2109 *value->Type()->ToAbstractType()); |
| 2106 var->set_index(index); | 2110 var->set_index(index); |
| 2107 return var; | 2111 return var; |
| 2108 } | 2112 } |
| 2109 | 2113 |
| 2110 | 2114 |
| 2111 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) { | 2115 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) { |
| 2112 Value* tmp = Bind(new LoadLocalInstr(*var)); | 2116 Value* tmp = Bind(new LoadLocalInstr(*var)); |
| 2113 owner()->DeallocateTemps(1); | 2117 owner()->DeallocateTemps(1); |
| 2114 ASSERT(GetCurrentTempLocalIndex() == var->index()); | 2118 ASSERT(GetCurrentTempLocalIndex() == var->index()); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2168 owner()->DeallocateTemps(num_temps); | 2172 owner()->DeallocateTemps(num_temps); |
| 2169 ReturnDefinition(new DropTempsInstr(num_temps, result_value)); | 2173 ReturnDefinition(new DropTempsInstr(num_temps, result_value)); |
| 2170 } else { | 2174 } else { |
| 2171 ReturnValue(result_value); | 2175 ReturnValue(result_value); |
| 2172 } | 2176 } |
| 2173 } | 2177 } |
| 2174 | 2178 |
| 2175 | 2179 |
| 2176 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { | 2180 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) { |
| 2177 const TypeArguments& type_args = | 2181 const TypeArguments& type_args = |
| 2178 TypeArguments::ZoneHandle(node->type().arguments()); | 2182 TypeArguments::ZoneHandle(I, node->type().arguments()); |
| 2179 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), | 2183 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), |
| 2180 type_args); | 2184 type_args); |
| 2181 Value* num_elements = | 2185 Value* num_elements = |
| 2182 Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(node->length())))); | 2186 Bind(new ConstantInstr(Smi::ZoneHandle(I, Smi::New(node->length())))); |
| 2183 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), | 2187 CreateArrayInstr* create = new CreateArrayInstr(node->token_pos(), |
| 2184 element_type, | 2188 element_type, |
| 2185 num_elements); | 2189 num_elements); |
| 2186 Value* array_val = Bind(create); | 2190 Value* array_val = Bind(create); |
| 2187 | 2191 |
| 2188 { LocalVariable* tmp_var = EnterTempLocalScope(array_val); | 2192 { LocalVariable* tmp_var = EnterTempLocalScope(array_val); |
| 2189 const intptr_t class_id = kArrayCid; | 2193 const intptr_t class_id = kArrayCid; |
| 2190 const intptr_t deopt_id = Isolate::kNoDeoptId; | 2194 const intptr_t deopt_id = Isolate::kNoDeoptId; |
| 2191 for (int i = 0; i < node->length(); ++i) { | 2195 for (int i = 0; i < node->length(); ++i) { |
| 2192 Value* array = Bind(new LoadLocalInstr(*tmp_var)); | 2196 Value* array = Bind(new LoadLocalInstr(*tmp_var)); |
| 2193 Value* index = Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(i)))); | 2197 Value* index = Bind(new ConstantInstr(Smi::ZoneHandle(I, Smi::New(i)))); |
| 2194 ValueGraphVisitor for_value(owner()); | 2198 ValueGraphVisitor for_value(owner()); |
| 2195 node->ElementAt(i)->Visit(&for_value); | 2199 node->ElementAt(i)->Visit(&for_value); |
| 2196 Append(for_value); | 2200 Append(for_value); |
| 2197 // No store barrier needed for constants. | 2201 // No store barrier needed for constants. |
| 2198 const StoreBarrierType emit_store_barrier = | 2202 const StoreBarrierType emit_store_barrier = |
| 2199 for_value.value()->BindsToConstant() | 2203 for_value.value()->BindsToConstant() |
| 2200 ? kNoStoreBarrier | 2204 ? kNoStoreBarrier |
| 2201 : kEmitStoreBarrier; | 2205 : kEmitStoreBarrier; |
| 2202 const intptr_t index_scale = Instance::ElementSizeFor(class_id); | 2206 const intptr_t index_scale = Instance::ElementSizeFor(class_id); |
| 2203 StoreIndexedInstr* store = new StoreIndexedInstr( | 2207 StoreIndexedInstr* store = new StoreIndexedInstr( |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2219 new StringInterpolateInstr(for_argument.value(), node->token_pos()); | 2223 new StringInterpolateInstr(for_argument.value(), node->token_pos()); |
| 2220 ReturnDefinition(instr); | 2224 ReturnDefinition(instr); |
| 2221 } | 2225 } |
| 2222 | 2226 |
| 2223 | 2227 |
| 2224 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { | 2228 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) { |
| 2225 const Function& function = node->function(); | 2229 const Function& function = node->function(); |
| 2226 | 2230 |
| 2227 if (function.IsImplicitStaticClosureFunction()) { | 2231 if (function.IsImplicitStaticClosureFunction()) { |
| 2228 const Instance& closure = | 2232 const Instance& closure = |
| 2229 Instance::ZoneHandle(function.ImplicitStaticClosure()); | 2233 Instance::ZoneHandle(I, function.ImplicitStaticClosure()); |
| 2230 ReturnDefinition(new ConstantInstr(closure)); | 2234 ReturnDefinition(new ConstantInstr(closure)); |
| 2231 return; | 2235 return; |
| 2232 } | 2236 } |
| 2233 const bool is_implicit = function.IsImplicitInstanceClosureFunction(); | 2237 const bool is_implicit = function.IsImplicitInstanceClosureFunction(); |
| 2234 ASSERT(is_implicit || function.IsNonImplicitClosureFunction()); | 2238 ASSERT(is_implicit || function.IsNonImplicitClosureFunction()); |
| 2235 // The context scope may have already been set by the non-optimizing | 2239 // The context scope may have already been set by the non-optimizing |
| 2236 // compiler. If it was not, set it here. | 2240 // compiler. If it was not, set it here. |
| 2237 if (function.context_scope() == ContextScope::null()) { | 2241 if (function.context_scope() == ContextScope::null()) { |
| 2238 ASSERT(!is_implicit); | 2242 ASSERT(!is_implicit); |
| 2239 const ContextScope& context_scope = ContextScope::ZoneHandle( | 2243 const ContextScope& context_scope = ContextScope::ZoneHandle( |
| 2240 node->scope()->PreserveOuterScope(owner()->context_level())); | 2244 I, node->scope()->PreserveOuterScope(owner()->context_level())); |
| 2241 ASSERT(!function.HasCode()); | 2245 ASSERT(!function.HasCode()); |
| 2242 ASSERT(function.context_scope() == ContextScope::null()); | 2246 ASSERT(function.context_scope() == ContextScope::null()); |
| 2243 function.set_context_scope(context_scope); | 2247 function.set_context_scope(context_scope); |
| 2244 const Class& cls = Class::Handle( | 2248 const Class& cls = Class::Handle( |
| 2245 owner()->parsed_function()->function().Owner()); | 2249 I, owner()->parsed_function()->function().Owner()); |
| 2246 // The closure is now properly setup, add it to the lookup table. | 2250 // The closure is now properly setup, add it to the lookup table. |
| 2247 // It is possible that the compiler creates more than one function | 2251 // It is possible that the compiler creates more than one function |
| 2248 // object for the same closure, e.g. when inlining nodes from | 2252 // object for the same closure, e.g. when inlining nodes from |
| 2249 // finally clauses. If we already have a function object for the | 2253 // finally clauses. If we already have a function object for the |
| 2250 // same closure, do not add a second one. We compare the origin | 2254 // same closure, do not add a second one. We compare the origin |
| 2251 // class, token position, and parent function to detect duplicates. | 2255 // class, token position, and parent function to detect duplicates. |
| 2252 // Note that we can have two different closure object for the same | 2256 // Note that we can have two different closure object for the same |
| 2253 // source text represntation of the closure: one with a non-closurized | 2257 // source text represntation of the closure: one with a non-closurized |
| 2254 // parent, and one with a closurized parent function. | 2258 // parent, and one with a closurized parent function. |
| 2255 | 2259 |
| 2256 const Function& found_func = Function::Handle( | 2260 const Function& found_func = Function::Handle( |
| 2257 cls.LookupClosureFunction(function.token_pos())); | 2261 I, cls.LookupClosureFunction(function.token_pos())); |
| 2258 | 2262 |
| 2259 if (found_func.IsNull() || | 2263 if (found_func.IsNull() || |
| 2260 (found_func.token_pos() != function.token_pos()) || | 2264 (found_func.token_pos() != function.token_pos()) || |
| 2261 (found_func.script() != function.script()) || | 2265 (found_func.script() != function.script()) || |
| 2262 (found_func.parent_function() != function.parent_function())) { | 2266 (found_func.parent_function() != function.parent_function())) { |
| 2263 cls.AddClosureFunction(function); | 2267 cls.AddClosureFunction(function); |
| 2264 } | 2268 } |
| 2265 } | 2269 } |
| 2266 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2270 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2267 new ZoneGrowableArray<PushArgumentInstr*>(1); | 2271 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 2268 ASSERT(function.context_scope() != ContextScope::null()); | 2272 ASSERT(function.context_scope() != ContextScope::null()); |
| 2269 | 2273 |
| 2270 // The function type of a closure may have type arguments. In that case, | 2274 // The function type of a closure may have type arguments. In that case, |
| 2271 // pass the type arguments of the instantiator. | 2275 // pass the type arguments of the instantiator. |
| 2272 const Class& cls = Class::ZoneHandle(function.signature_class()); | 2276 const Class& cls = Class::ZoneHandle(I, function.signature_class()); |
| 2273 ASSERT(!cls.IsNull()); | 2277 ASSERT(!cls.IsNull()); |
| 2274 const bool requires_type_arguments = cls.NumTypeArguments() > 0; | 2278 const bool requires_type_arguments = cls.NumTypeArguments() > 0; |
| 2275 Value* type_arguments = NULL; | 2279 Value* type_arguments = NULL; |
| 2276 if (requires_type_arguments) { | 2280 if (requires_type_arguments) { |
| 2277 ASSERT(cls.type_arguments_field_offset() == | 2281 ASSERT(cls.type_arguments_field_offset() == |
| 2278 Closure::type_arguments_offset()); | 2282 Closure::type_arguments_offset()); |
| 2279 ASSERT(cls.instance_size() == Closure::InstanceSize()); | 2283 ASSERT(cls.instance_size() == Closure::InstanceSize()); |
| 2280 const Class& instantiator_class = Class::Handle( | 2284 const Class& instantiator_class = Class::Handle( |
| 2281 owner()->parsed_function()->function().Owner()); | 2285 I, owner()->parsed_function()->function().Owner()); |
| 2282 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), | 2286 type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), |
| 2283 instantiator_class, | 2287 instantiator_class, |
| 2284 NULL); | 2288 NULL); |
| 2285 arguments->Add(PushArgument(type_arguments)); | 2289 arguments->Add(PushArgument(type_arguments)); |
| 2286 } | 2290 } |
| 2287 AllocateObjectInstr* alloc = new AllocateObjectInstr(node->token_pos(), | 2291 AllocateObjectInstr* alloc = new AllocateObjectInstr(node->token_pos(), |
| 2288 cls, | 2292 cls, |
| 2289 arguments); | 2293 arguments); |
| 2290 alloc->set_closure_function(function); | 2294 alloc->set_closure_function(function); |
| 2291 | 2295 |
| 2292 Value* closure_val = Bind(alloc); | 2296 Value* closure_val = Bind(alloc); |
| 2293 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val); | 2297 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val); |
| 2294 // Store function. | 2298 // Store function. |
| 2295 Value* closure_tmp_val = Bind(new LoadLocalInstr(*closure_tmp_var)); | 2299 Value* closure_tmp_val = Bind(new LoadLocalInstr(*closure_tmp_var)); |
| 2296 Value* func_val = | 2300 Value* func_val = |
| 2297 Bind(new ConstantInstr(Function::ZoneHandle(function.raw()))); | 2301 Bind(new ConstantInstr(Function::ZoneHandle(I, function.raw()))); |
| 2298 Do(new StoreInstanceFieldInstr(Closure::function_offset(), | 2302 Do(new StoreInstanceFieldInstr(Closure::function_offset(), |
| 2299 closure_tmp_val, | 2303 closure_tmp_val, |
| 2300 func_val, | 2304 func_val, |
| 2301 kEmitStoreBarrier, | 2305 kEmitStoreBarrier, |
| 2302 node->token_pos())); | 2306 node->token_pos())); |
| 2303 if (is_implicit) { | 2307 if (is_implicit) { |
| 2304 // Create new context containing the receiver. | 2308 // Create new context containing the receiver. |
| 2305 const intptr_t kNumContextVariables = 1; // The receiver. | 2309 const intptr_t kNumContextVariables = 1; // The receiver. |
| 2306 Value* allocated_context = | 2310 Value* allocated_context = |
| 2307 Bind(new AllocateContextInstr(node->token_pos(), | 2311 Bind(new AllocateContextInstr(node->token_pos(), |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2444 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 2448 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 2445 Value* closure_val = Bind(new LoadLocalInstr(*tmp_var)); | 2449 Value* closure_val = Bind(new LoadLocalInstr(*tmp_var)); |
| 2446 PushArgumentInstr* push_closure = PushArgument(closure_val); | 2450 PushArgumentInstr* push_closure = PushArgument(closure_val); |
| 2447 arguments->Add(push_closure); | 2451 arguments->Add(push_closure); |
| 2448 BuildPushArguments(*node->arguments(), arguments); | 2452 BuildPushArguments(*node->arguments(), arguments); |
| 2449 | 2453 |
| 2450 // Save context around the call. | 2454 // Save context around the call. |
| 2451 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); | 2455 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); |
| 2452 BuildSaveContext(*owner()->parsed_function()->saved_current_context_var()); | 2456 BuildSaveContext(*owner()->parsed_function()->saved_current_context_var()); |
| 2453 closure_val = Bind(new LoadLocalInstr(*tmp_var)); | 2457 closure_val = Bind(new LoadLocalInstr(*tmp_var)); |
| 2454 LoadFieldInstr* context_load = new LoadFieldInstr(closure_val, | 2458 LoadFieldInstr* context_load = new LoadFieldInstr( |
| 2455 Closure::context_offset(), | 2459 closure_val, |
| 2456 AbstractType::ZoneHandle(), | 2460 Closure::context_offset(), |
| 2457 node->token_pos()); | 2461 AbstractType::ZoneHandle(I, AbstractType::null()), |
| 2462 node->token_pos()); |
| 2458 context_load->set_is_immutable(true); | 2463 context_load->set_is_immutable(true); |
| 2459 Value* context_val = Bind(context_load); | 2464 Value* context_val = Bind(context_load); |
| 2460 AddInstruction(new StoreContextInstr(context_val)); | 2465 AddInstruction(new StoreContextInstr(context_val)); |
| 2461 closure_val = Bind(new LoadLocalInstr(*tmp_var)); | 2466 closure_val = Bind(new LoadLocalInstr(*tmp_var)); |
| 2462 LoadFieldInstr* function_load = | 2467 LoadFieldInstr* function_load = new LoadFieldInstr( |
| 2463 new LoadFieldInstr(closure_val, | 2468 closure_val, |
| 2464 Closure::function_offset(), | 2469 Closure::function_offset(), |
| 2465 AbstractType::ZoneHandle(), | 2470 AbstractType::ZoneHandle(I, AbstractType::null()), |
| 2466 node->token_pos()); | 2471 node->token_pos()); |
| 2467 function_load->set_is_immutable(true); | 2472 function_load->set_is_immutable(true); |
| 2468 Value* function_val = Bind(function_load); | 2473 Value* function_val = Bind(function_load); |
| 2469 Definition* closure_call = | 2474 Definition* closure_call = |
| 2470 new ClosureCallInstr(function_val, node, arguments); | 2475 new ClosureCallInstr(function_val, node, arguments); |
| 2471 if (result_needed) { | 2476 if (result_needed) { |
| 2472 Value* result = Bind(closure_call); | 2477 Value* result = Bind(closure_call); |
| 2473 Do(new StoreLocalInstr(*tmp_var, result)); | 2478 Do(new StoreLocalInstr(*tmp_var, result)); |
| 2474 // Restore context from temp. | 2479 // Restore context from temp. |
| 2475 BuildRestoreContext( | 2480 BuildRestoreContext( |
| 2476 *owner()->parsed_function()->saved_current_context_var()); | 2481 *owner()->parsed_function()->saved_current_context_var()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2496 | 2501 |
| 2497 | 2502 |
| 2498 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 2503 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| 2499 Value* context = Bind(new CurrentContextInstr()); | 2504 Value* context = Bind(new CurrentContextInstr()); |
| 2500 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); | 2505 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); |
| 2501 AddInstruction(new StoreContextInstr(clone)); | 2506 AddInstruction(new StoreContextInstr(clone)); |
| 2502 } | 2507 } |
| 2503 | 2508 |
| 2504 | 2509 |
| 2505 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) { | 2510 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) { |
| 2506 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 2511 const Class& cls = Class::ZoneHandle(I, node->constructor().Owner()); |
| 2507 const bool cls_is_parameterized = cls.NumTypeArguments() > 0; | 2512 const bool cls_is_parameterized = cls.NumTypeArguments() > 0; |
| 2508 | 2513 |
| 2509 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = | 2514 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = |
| 2510 new ZoneGrowableArray<PushArgumentInstr*>(cls_is_parameterized ? 1 : 0); | 2515 new ZoneGrowableArray<PushArgumentInstr*>(cls_is_parameterized ? 1 : 0); |
| 2511 if (cls_is_parameterized) { | 2516 if (cls_is_parameterized) { |
| 2512 Value* type_args = BuildInstantiatedTypeArguments(node->token_pos(), | 2517 Value* type_args = BuildInstantiatedTypeArguments(node->token_pos(), |
| 2513 node->type_arguments()); | 2518 node->type_arguments()); |
| 2514 allocate_arguments->Add(PushArgument(type_args)); | 2519 allocate_arguments->Add(PushArgument(type_args)); |
| 2515 } | 2520 } |
| 2516 | 2521 |
| 2517 Definition* allocation = new AllocateObjectInstr( | 2522 Definition* allocation = new AllocateObjectInstr( |
| 2518 node->token_pos(), | 2523 node->token_pos(), |
| 2519 Class::ZoneHandle(node->constructor().Owner()), | 2524 Class::ZoneHandle(I, node->constructor().Owner()), |
| 2520 allocate_arguments); | 2525 allocate_arguments); |
| 2521 | 2526 |
| 2522 return Bind(allocation); | 2527 return Bind(allocation); |
| 2523 } | 2528 } |
| 2524 | 2529 |
| 2525 | 2530 |
| 2526 void EffectGraphVisitor::BuildConstructorCall( | 2531 void EffectGraphVisitor::BuildConstructorCall( |
| 2527 ConstructorCallNode* node, | 2532 ConstructorCallNode* node, |
| 2528 PushArgumentInstr* push_alloc_value) { | 2533 PushArgumentInstr* push_alloc_value) { |
| 2529 Value* ctor_arg = Bind( | 2534 Value* ctor_arg = Bind( |
| 2530 new ConstantInstr(Smi::ZoneHandle(Smi::New(Function::kCtorPhaseAll)))); | 2535 new ConstantInstr(Smi::ZoneHandle(I, Smi::New(Function::kCtorPhaseAll)))); |
| 2531 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); | 2536 PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg); |
| 2532 | 2537 |
| 2533 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2538 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2534 new ZoneGrowableArray<PushArgumentInstr*>(2); | 2539 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 2535 arguments->Add(push_alloc_value); | 2540 arguments->Add(push_alloc_value); |
| 2536 arguments->Add(push_ctor_arg); | 2541 arguments->Add(push_ctor_arg); |
| 2537 | 2542 |
| 2538 BuildPushArguments(*node->arguments(), arguments); | 2543 BuildPushArguments(*node->arguments(), arguments); |
| 2539 Do(new StaticCallInstr(node->token_pos(), | 2544 Do(new StaticCallInstr(node->token_pos(), |
| 2540 node->constructor(), | 2545 node->constructor(), |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2604 // No need to preserve allocated value (simpler than in ValueGraphVisitor). | 2609 // No need to preserve allocated value (simpler than in ValueGraphVisitor). |
| 2605 Value* allocated_value = BuildObjectAllocation(node); | 2610 Value* allocated_value = BuildObjectAllocation(node); |
| 2606 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 2611 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 2607 BuildConstructorCall(node, push_allocated_value); | 2612 BuildConstructorCall(node, push_allocated_value); |
| 2608 } | 2613 } |
| 2609 | 2614 |
| 2610 | 2615 |
| 2611 Value* EffectGraphVisitor::BuildInstantiator(const Class& instantiator_class) { | 2616 Value* EffectGraphVisitor::BuildInstantiator(const Class& instantiator_class) { |
| 2612 ASSERT(instantiator_class.NumTypeParameters() > 0); | 2617 ASSERT(instantiator_class.NumTypeParameters() > 0); |
| 2613 Function& outer_function = | 2618 Function& outer_function = |
| 2614 Function::Handle(owner()->parsed_function()->function().raw()); | 2619 Function::Handle(I, owner()->parsed_function()->function().raw()); |
| 2615 while (outer_function.IsLocalFunction()) { | 2620 while (outer_function.IsLocalFunction()) { |
| 2616 outer_function = outer_function.parent_function(); | 2621 outer_function = outer_function.parent_function(); |
| 2617 } | 2622 } |
| 2618 if (outer_function.IsFactory()) { | 2623 if (outer_function.IsFactory()) { |
| 2619 return NULL; | 2624 return NULL; |
| 2620 } | 2625 } |
| 2621 | 2626 |
| 2622 LocalVariable* instantiator = owner()->parsed_function()->instantiator(); | 2627 LocalVariable* instantiator = owner()->parsed_function()->instantiator(); |
| 2623 ASSERT(instantiator != NULL); | 2628 ASSERT(instantiator != NULL); |
| 2624 Value* result = Bind(BuildLoadLocal(*instantiator)); | 2629 Value* result = Bind(BuildLoadLocal(*instantiator)); |
| 2625 return result; | 2630 return result; |
| 2626 } | 2631 } |
| 2627 | 2632 |
| 2628 | 2633 |
| 2629 // 'expression_temp_var' may not be used inside this method if 'instantiator' | 2634 // 'expression_temp_var' may not be used inside this method if 'instantiator' |
| 2630 // is not NULL. | 2635 // is not NULL. |
| 2631 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 2636 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| 2632 intptr_t token_pos, | 2637 intptr_t token_pos, |
| 2633 const Class& instantiator_class, | 2638 const Class& instantiator_class, |
| 2634 Value* instantiator) { | 2639 Value* instantiator) { |
| 2635 if (instantiator_class.NumTypeParameters() == 0) { | 2640 if (instantiator_class.NumTypeParameters() == 0) { |
| 2636 // The type arguments are compile time constants. | 2641 // The type arguments are compile time constants. |
| 2637 TypeArguments& type_arguments = TypeArguments::ZoneHandle(); | 2642 TypeArguments& type_arguments = |
| 2643 TypeArguments::ZoneHandle(I, TypeArguments::null()); |
| 2638 // Type is temporary. Only its type arguments are preserved. | 2644 // Type is temporary. Only its type arguments are preserved. |
| 2639 Type& type = Type::Handle( | 2645 Type& type = Type::Handle( |
| 2646 I, |
| 2640 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); | 2647 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); |
| 2641 type ^= ClassFinalizer::FinalizeType( | 2648 type ^= ClassFinalizer::FinalizeType( |
| 2642 instantiator_class, type, ClassFinalizer::kFinalize); | 2649 instantiator_class, type, ClassFinalizer::kFinalize); |
| 2643 ASSERT(!type.IsMalformedOrMalbounded()); | 2650 ASSERT(!type.IsMalformedOrMalbounded()); |
| 2644 type_arguments = type.arguments(); | 2651 type_arguments = type.arguments(); |
| 2645 type_arguments = type_arguments.Canonicalize(); | 2652 type_arguments = type_arguments.Canonicalize(); |
| 2646 return Bind(new ConstantInstr(type_arguments)); | 2653 return Bind(new ConstantInstr(type_arguments)); |
| 2647 } | 2654 } |
| 2648 Function& outer_function = | 2655 Function& outer_function = |
| 2649 Function::Handle(owner()->parsed_function()->function().raw()); | 2656 Function::Handle(I, owner()->parsed_function()->function().raw()); |
| 2650 while (outer_function.IsLocalFunction()) { | 2657 while (outer_function.IsLocalFunction()) { |
| 2651 outer_function = outer_function.parent_function(); | 2658 outer_function = outer_function.parent_function(); |
| 2652 } | 2659 } |
| 2653 if (outer_function.IsFactory()) { | 2660 if (outer_function.IsFactory()) { |
| 2654 // No instantiator for factories. | 2661 // No instantiator for factories. |
| 2655 ASSERT(instantiator == NULL); | 2662 ASSERT(instantiator == NULL); |
| 2656 LocalVariable* instantiator_var = | 2663 LocalVariable* instantiator_var = |
| 2657 owner()->parsed_function()->instantiator(); | 2664 owner()->parsed_function()->instantiator(); |
| 2658 ASSERT(instantiator_var != NULL); | 2665 ASSERT(instantiator_var != NULL); |
| 2659 return Bind(BuildLoadLocal(*instantiator_var)); | 2666 return Bind(BuildLoadLocal(*instantiator_var)); |
| 2660 } | 2667 } |
| 2661 if (instantiator == NULL) { | 2668 if (instantiator == NULL) { |
| 2662 instantiator = BuildInstantiator(instantiator_class); | 2669 instantiator = BuildInstantiator(instantiator_class); |
| 2663 } | 2670 } |
| 2664 // The instantiator is the receiver of the caller, which is not a factory. | 2671 // The instantiator is the receiver of the caller, which is not a factory. |
| 2665 // The receiver cannot be null; extract its TypeArguments object. | 2672 // The receiver cannot be null; extract its TypeArguments object. |
| 2666 // Note that in the factory case, the instantiator is the first parameter | 2673 // Note that in the factory case, the instantiator is the first parameter |
| 2667 // of the factory, i.e. already a TypeArguments object. | 2674 // of the factory, i.e. already a TypeArguments object. |
| 2668 intptr_t type_arguments_field_offset = | 2675 intptr_t type_arguments_field_offset = |
| 2669 instantiator_class.type_arguments_field_offset(); | 2676 instantiator_class.type_arguments_field_offset(); |
| 2670 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); | 2677 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); |
| 2671 | 2678 |
| 2672 return Bind(new LoadFieldInstr( | 2679 return Bind(new LoadFieldInstr( |
| 2673 instantiator, | 2680 instantiator, |
| 2674 type_arguments_field_offset, | 2681 type_arguments_field_offset, |
| 2675 Type::ZoneHandle(), // Not an instance, no type. | 2682 Type::ZoneHandle(I, Type::null()), // Not an instance, no type. |
| 2676 Scanner::kNoSourcePos)); | 2683 Scanner::kNoSourcePos)); |
| 2677 } | 2684 } |
| 2678 | 2685 |
| 2679 | 2686 |
| 2680 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( | 2687 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( |
| 2681 intptr_t token_pos, | 2688 intptr_t token_pos, |
| 2682 const TypeArguments& type_arguments) { | 2689 const TypeArguments& type_arguments) { |
| 2683 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { | 2690 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
| 2684 return Bind(new ConstantInstr(type_arguments)); | 2691 return Bind(new ConstantInstr(type_arguments)); |
| 2685 } | 2692 } |
| 2686 // The type arguments are uninstantiated. | 2693 // The type arguments are uninstantiated. |
| 2687 const Class& instantiator_class = Class::ZoneHandle( | 2694 const Class& instantiator_class = Class::ZoneHandle( |
| 2688 owner()->parsed_function()->function().Owner()); | 2695 I, owner()->parsed_function()->function().Owner()); |
| 2689 Value* instantiator_value = | 2696 Value* instantiator_value = |
| 2690 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 2697 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 2691 const bool use_instantiator_type_args = | 2698 const bool use_instantiator_type_args = |
| 2692 type_arguments.IsUninstantiatedIdentity() || | 2699 type_arguments.IsUninstantiatedIdentity() || |
| 2693 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class); | 2700 type_arguments.CanShareInstantiatorTypeArguments(instantiator_class); |
| 2694 if (use_instantiator_type_args) { | 2701 if (use_instantiator_type_args) { |
| 2695 return instantiator_value; | 2702 return instantiator_value; |
| 2696 } else { | 2703 } else { |
| 2697 return Bind(new InstantiateTypeArgumentsInstr(token_pos, | 2704 return Bind(new InstantiateTypeArgumentsInstr(token_pos, |
| 2698 type_arguments, | 2705 type_arguments, |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2728 | 2735 |
| 2729 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 2736 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 2730 ValueGraphVisitor for_receiver(owner()); | 2737 ValueGraphVisitor for_receiver(owner()); |
| 2731 node->receiver()->Visit(&for_receiver); | 2738 node->receiver()->Visit(&for_receiver); |
| 2732 Append(for_receiver); | 2739 Append(for_receiver); |
| 2733 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 2740 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 2734 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2741 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2735 new ZoneGrowableArray<PushArgumentInstr*>(1); | 2742 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 2736 arguments->Add(push_receiver); | 2743 arguments->Add(push_receiver); |
| 2737 const String& name = | 2744 const String& name = |
| 2738 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 2745 String::ZoneHandle(I, Field::GetterSymbol(node->field_name())); |
| 2739 InstanceCallInstr* call = new InstanceCallInstr( | 2746 InstanceCallInstr* call = new InstanceCallInstr( |
| 2740 node->token_pos(), | 2747 node->token_pos(), |
| 2741 name, | 2748 name, |
| 2742 Token::kGET, | 2749 Token::kGET, |
| 2743 arguments, Object::null_array(), | 2750 arguments, Object::null_array(), |
| 2744 1, | 2751 1, |
| 2745 owner()->ic_data_array()); | 2752 owner()->ic_data_array()); |
| 2746 ReturnDefinition(call); | 2753 ReturnDefinition(call); |
| 2747 } | 2754 } |
| 2748 | 2755 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2768 } | 2775 } |
| 2769 arguments->Add(PushArgument(value)); | 2776 arguments->Add(PushArgument(value)); |
| 2770 } | 2777 } |
| 2771 | 2778 |
| 2772 | 2779 |
| 2773 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 2780 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 2774 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2781 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2775 new ZoneGrowableArray<PushArgumentInstr*>(2); | 2782 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 2776 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded); | 2783 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded); |
| 2777 const String& name = | 2784 const String& name = |
| 2778 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 2785 String::ZoneHandle(I, Field::SetterSymbol(node->field_name())); |
| 2779 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), | 2786 InstanceCallInstr* call = new InstanceCallInstr(node->token_pos(), |
| 2780 name, | 2787 name, |
| 2781 Token::kSET, | 2788 Token::kSET, |
| 2782 arguments, | 2789 arguments, |
| 2783 Object::null_array(), | 2790 Object::null_array(), |
| 2784 2, // Checked arg count. | 2791 2, // Checked arg count. |
| 2785 owner()->ic_data_array()); | 2792 owner()->ic_data_array()); |
| 2786 ReturnDefinition(call); | 2793 ReturnDefinition(call); |
| 2787 } | 2794 } |
| 2788 | 2795 |
| 2789 | 2796 |
| 2790 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 2797 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 2791 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2798 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2792 new ZoneGrowableArray<PushArgumentInstr*>(2); | 2799 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 2793 BuildInstanceSetterArguments(node, arguments, kResultNeeded); | 2800 BuildInstanceSetterArguments(node, arguments, kResultNeeded); |
| 2794 const String& name = | 2801 const String& name = |
| 2795 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 2802 String::ZoneHandle(I, Field::SetterSymbol(node->field_name())); |
| 2796 Do(new InstanceCallInstr(node->token_pos(), | 2803 Do(new InstanceCallInstr(node->token_pos(), |
| 2797 name, | 2804 name, |
| 2798 Token::kSET, | 2805 Token::kSET, |
| 2799 arguments, | 2806 arguments, |
| 2800 Object::null_array(), | 2807 Object::null_array(), |
| 2801 2, // Checked argument count. | 2808 2, // Checked argument count. |
| 2802 owner()->ic_data_array())); | 2809 owner()->ic_data_array())); |
| 2803 ReturnDefinition(BuildLoadExprTemp()); | 2810 ReturnDefinition(BuildLoadExprTemp()); |
| 2804 } | 2811 } |
| 2805 | 2812 |
| 2806 | 2813 |
| 2807 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { | 2814 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { |
| 2808 const String& getter_name = | 2815 const String& getter_name = |
| 2809 String::ZoneHandle(Field::GetterSymbol(node->field_name())); | 2816 String::ZoneHandle(I, Field::GetterSymbol(node->field_name())); |
| 2810 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2817 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2811 new ZoneGrowableArray<PushArgumentInstr*>(); | 2818 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 2812 Function& getter_function = Function::ZoneHandle(); | 2819 Function& getter_function = Function::ZoneHandle(I, Function::null()); |
| 2813 if (node->is_super_getter()) { | 2820 if (node->is_super_getter()) { |
| 2814 // Statically resolved instance getter, i.e. "super getter". | 2821 // Statically resolved instance getter, i.e. "super getter". |
| 2815 ASSERT(node->receiver() != NULL); | 2822 ASSERT(node->receiver() != NULL); |
| 2816 getter_function = Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); | 2823 getter_function = Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name); |
| 2817 if (getter_function.IsNull()) { | 2824 if (getter_function.IsNull()) { |
| 2818 // Resolve and call noSuchMethod. | 2825 // Resolve and call noSuchMethod. |
| 2819 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); | 2826 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); |
| 2820 arguments->Add(node->receiver()); | 2827 arguments->Add(node->receiver()); |
| 2821 StaticCallInstr* call = | 2828 StaticCallInstr* call = |
| 2822 BuildStaticNoSuchMethodCall(node->cls(), | 2829 BuildStaticNoSuchMethodCall(node->cls(), |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2871 Object::null_array(), // No names | 2878 Object::null_array(), // No names |
| 2872 arguments, | 2879 arguments, |
| 2873 owner()->ic_data_array()); | 2880 owner()->ic_data_array()); |
| 2874 ReturnDefinition(call); | 2881 ReturnDefinition(call); |
| 2875 } | 2882 } |
| 2876 | 2883 |
| 2877 | 2884 |
| 2878 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, | 2885 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, |
| 2879 bool result_is_needed) { | 2886 bool result_is_needed) { |
| 2880 const String& setter_name = | 2887 const String& setter_name = |
| 2881 String::ZoneHandle(Field::SetterSymbol(node->field_name())); | 2888 String::ZoneHandle(I, Field::SetterSymbol(node->field_name())); |
| 2882 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2889 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2883 new ZoneGrowableArray<PushArgumentInstr*>(1); | 2890 new ZoneGrowableArray<PushArgumentInstr*>(1); |
| 2884 // A super setter is an instance setter whose setter function is | 2891 // A super setter is an instance setter whose setter function is |
| 2885 // resolved at compile time (in the caller instance getter's super class). | 2892 // resolved at compile time (in the caller instance getter's super class). |
| 2886 // Unlike a static getter, a super getter has a receiver parameter. | 2893 // Unlike a static getter, a super getter has a receiver parameter. |
| 2887 const bool is_super_setter = (node->receiver() != NULL); | 2894 const bool is_super_setter = (node->receiver() != NULL); |
| 2888 Function& setter_function = | 2895 Function& setter_function = |
| 2889 Function::ZoneHandle(is_super_setter | 2896 Function::ZoneHandle(I, is_super_setter |
| 2890 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) | 2897 ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name) |
| 2891 : node->cls().LookupStaticFunction(setter_name)); | 2898 : node->cls().LookupStaticFunction(setter_name)); |
| 2892 StaticCallInstr* call; | 2899 StaticCallInstr* call; |
| 2893 if (setter_function.IsNull()) { | 2900 if (setter_function.IsNull()) { |
| 2894 if (is_super_setter) { | 2901 if (is_super_setter) { |
| 2895 ASSERT(node->receiver() != NULL); | 2902 ASSERT(node->receiver() != NULL); |
| 2896 // Resolve and call noSuchMethod. | 2903 // Resolve and call noSuchMethod. |
| 2897 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); | 2904 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); |
| 2898 arguments->Add(node->receiver()); | 2905 arguments->Add(node->receiver()); |
| 2899 arguments->Add(node->value()); | 2906 arguments->Add(node->value()); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3013 case MethodRecognizer::kStringBaseLength: | 3020 case MethodRecognizer::kStringBaseLength: |
| 3014 case MethodRecognizer::kStringBaseIsEmpty: { | 3021 case MethodRecognizer::kStringBaseIsEmpty: { |
| 3015 Value* receiver = Bind(BuildLoadThisVar(node->scope())); | 3022 Value* receiver = Bind(BuildLoadThisVar(node->scope())); |
| 3016 // Treat length loads as mutable (i.e. affected by side effects) to | 3023 // Treat length loads as mutable (i.e. affected by side effects) to |
| 3017 // avoid hoisting them since we can't hoist the preceding class-check. | 3024 // avoid hoisting them since we can't hoist the preceding class-check. |
| 3018 // This is because of externalization of strings that affects their | 3025 // This is because of externalization of strings that affects their |
| 3019 // class-id. | 3026 // class-id. |
| 3020 LoadFieldInstr* load = new LoadFieldInstr( | 3027 LoadFieldInstr* load = new LoadFieldInstr( |
| 3021 receiver, | 3028 receiver, |
| 3022 String::length_offset(), | 3029 String::length_offset(), |
| 3023 Type::ZoneHandle(Type::SmiType()), | 3030 Type::ZoneHandle(I, Type::SmiType()), |
| 3024 node->token_pos()); | 3031 node->token_pos()); |
| 3025 load->set_result_cid(kSmiCid); | 3032 load->set_result_cid(kSmiCid); |
| 3026 load->set_recognized_kind(MethodRecognizer::kStringBaseLength); | 3033 load->set_recognized_kind(MethodRecognizer::kStringBaseLength); |
| 3027 if (kind == MethodRecognizer::kStringBaseLength) { | 3034 if (kind == MethodRecognizer::kStringBaseLength) { |
| 3028 return ReturnDefinition(load); | 3035 return ReturnDefinition(load); |
| 3029 } | 3036 } |
| 3030 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty); | 3037 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty); |
| 3031 Value* zero_val = Bind(new ConstantInstr(Smi::ZoneHandle(Smi::New(0)))); | 3038 Value* zero_val = Bind(new ConstantInstr( |
| 3039 Smi::ZoneHandle(I, Smi::New(0)))); |
| 3032 Value* load_val = Bind(load); | 3040 Value* load_val = Bind(load); |
| 3033 StrictCompareInstr* compare = | 3041 StrictCompareInstr* compare = |
| 3034 new StrictCompareInstr(node->token_pos(), | 3042 new StrictCompareInstr(node->token_pos(), |
| 3035 Token::kEQ_STRICT, | 3043 Token::kEQ_STRICT, |
| 3036 load_val, | 3044 load_val, |
| 3037 zero_val, | 3045 zero_val, |
| 3038 false); // No number check. | 3046 false); // No number check. |
| 3039 return ReturnDefinition(compare); | 3047 return ReturnDefinition(compare); |
| 3040 } | 3048 } |
| 3041 case MethodRecognizer::kGrowableArrayLength: | 3049 case MethodRecognizer::kGrowableArrayLength: |
| 3042 case MethodRecognizer::kObjectArrayLength: | 3050 case MethodRecognizer::kObjectArrayLength: |
| 3043 case MethodRecognizer::kImmutableArrayLength: | 3051 case MethodRecognizer::kImmutableArrayLength: |
| 3044 case MethodRecognizer::kTypedDataLength: { | 3052 case MethodRecognizer::kTypedDataLength: { |
| 3045 Value* receiver = Bind(BuildLoadThisVar(node->scope())); | 3053 Value* receiver = Bind(BuildLoadThisVar(node->scope())); |
| 3046 LoadFieldInstr* load = new LoadFieldInstr( | 3054 LoadFieldInstr* load = new LoadFieldInstr( |
| 3047 receiver, | 3055 receiver, |
| 3048 OffsetForLengthGetter(kind), | 3056 OffsetForLengthGetter(kind), |
| 3049 Type::ZoneHandle(Type::SmiType()), | 3057 Type::ZoneHandle(I, Type::SmiType()), |
| 3050 node->token_pos()); | 3058 node->token_pos()); |
| 3051 load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength); | 3059 load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength); |
| 3052 load->set_result_cid(kSmiCid); | 3060 load->set_result_cid(kSmiCid); |
| 3053 load->set_recognized_kind(kind); | 3061 load->set_recognized_kind(kind); |
| 3054 return ReturnDefinition(load); | 3062 return ReturnDefinition(load); |
| 3055 } | 3063 } |
| 3056 case MethodRecognizer::kObjectCid: | 3064 case MethodRecognizer::kObjectCid: |
| 3057 case MethodRecognizer::kTypedListBaseCid: { | 3065 case MethodRecognizer::kTypedListBaseCid: { |
| 3058 Value* receiver = Bind(BuildLoadThisVar(node->scope())); | 3066 Value* receiver = Bind(BuildLoadThisVar(node->scope())); |
| 3059 LoadClassIdInstr* load = new LoadClassIdInstr(receiver); | 3067 LoadClassIdInstr* load = new LoadClassIdInstr(receiver); |
| 3060 return ReturnDefinition(load); | 3068 return ReturnDefinition(load); |
| 3061 } | 3069 } |
| 3062 case MethodRecognizer::kGrowableArrayCapacity: { | 3070 case MethodRecognizer::kGrowableArrayCapacity: { |
| 3063 Value* receiver = Bind(BuildLoadThisVar(node->scope())); | 3071 Value* receiver = Bind(BuildLoadThisVar(node->scope())); |
| 3064 LoadFieldInstr* data_load = new LoadFieldInstr( | 3072 LoadFieldInstr* data_load = new LoadFieldInstr( |
| 3065 receiver, | 3073 receiver, |
| 3066 Array::data_offset(), | 3074 Array::data_offset(), |
| 3067 Type::ZoneHandle(Type::DynamicType()), | 3075 Type::ZoneHandle(I, Type::DynamicType()), |
| 3068 node->token_pos()); | 3076 node->token_pos()); |
| 3069 data_load->set_result_cid(kArrayCid); | 3077 data_load->set_result_cid(kArrayCid); |
| 3070 Value* data = Bind(data_load); | 3078 Value* data = Bind(data_load); |
| 3071 LoadFieldInstr* length_load = new LoadFieldInstr( | 3079 LoadFieldInstr* length_load = new LoadFieldInstr( |
| 3072 data, | 3080 data, |
| 3073 Array::length_offset(), | 3081 Array::length_offset(), |
| 3074 Type::ZoneHandle(Type::SmiType()), | 3082 Type::ZoneHandle(I, Type::SmiType()), |
| 3075 node->token_pos()); | 3083 node->token_pos()); |
| 3076 length_load->set_result_cid(kSmiCid); | 3084 length_load->set_result_cid(kSmiCid); |
| 3077 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength); | 3085 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength); |
| 3078 return ReturnDefinition(length_load); | 3086 return ReturnDefinition(length_load); |
| 3079 } | 3087 } |
| 3080 default: | 3088 default: |
| 3081 break; | 3089 break; |
| 3082 } | 3090 } |
| 3083 } | 3091 } |
| 3084 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); | 3092 InlineBailout("EffectGraphVisitor::VisitNativeBodyNode"); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3135 | 3143 |
| 3136 | 3144 |
| 3137 void EffectGraphVisitor::VisitLoadInstanceFieldNode( | 3145 void EffectGraphVisitor::VisitLoadInstanceFieldNode( |
| 3138 LoadInstanceFieldNode* node) { | 3146 LoadInstanceFieldNode* node) { |
| 3139 ValueGraphVisitor for_instance(owner()); | 3147 ValueGraphVisitor for_instance(owner()); |
| 3140 node->instance()->Visit(&for_instance); | 3148 node->instance()->Visit(&for_instance); |
| 3141 Append(for_instance); | 3149 Append(for_instance); |
| 3142 LoadFieldInstr* load = new LoadFieldInstr( | 3150 LoadFieldInstr* load = new LoadFieldInstr( |
| 3143 for_instance.value(), | 3151 for_instance.value(), |
| 3144 &node->field(), | 3152 &node->field(), |
| 3145 AbstractType::ZoneHandle(node->field().type()), | 3153 AbstractType::ZoneHandle(I, node->field().type()), |
| 3146 node->token_pos()); | 3154 node->token_pos()); |
| 3147 if (node->field().guarded_cid() != kIllegalCid) { | 3155 if (node->field().guarded_cid() != kIllegalCid) { |
| 3148 if (!node->field().is_nullable() || | 3156 if (!node->field().is_nullable() || |
| 3149 (node->field().guarded_cid() == kNullCid)) { | 3157 (node->field().guarded_cid() == kNullCid)) { |
| 3150 load->set_result_cid(node->field().guarded_cid()); | 3158 load->set_result_cid(node->field().guarded_cid()); |
| 3151 } | 3159 } |
| 3152 FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field()); | 3160 FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field()); |
| 3153 } | 3161 } |
| 3154 ReturnDefinition(load); | 3162 ReturnDefinition(load); |
| 3155 } | 3163 } |
| 3156 | 3164 |
| 3157 | 3165 |
| 3158 void EffectGraphVisitor::VisitStoreInstanceFieldNode( | 3166 void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| 3159 StoreInstanceFieldNode* node) { | 3167 StoreInstanceFieldNode* node) { |
| 3160 ValueGraphVisitor for_instance(owner()); | 3168 ValueGraphVisitor for_instance(owner()); |
| 3161 node->instance()->Visit(&for_instance); | 3169 node->instance()->Visit(&for_instance); |
| 3162 Append(for_instance); | 3170 Append(for_instance); |
| 3163 ValueGraphVisitor for_value(owner()); | 3171 ValueGraphVisitor for_value(owner()); |
| 3164 node->value()->Visit(&for_value); | 3172 node->value()->Visit(&for_value); |
| 3165 Append(for_value); | 3173 Append(for_value); |
| 3166 Value* store_value = for_value.value(); | 3174 Value* store_value = for_value.value(); |
| 3167 if (FLAG_enable_type_checks) { | 3175 if (FLAG_enable_type_checks) { |
| 3168 const AbstractType& type = AbstractType::ZoneHandle(node->field().type()); | 3176 const AbstractType& type = |
| 3169 const String& dst_name = String::ZoneHandle(node->field().name()); | 3177 AbstractType::ZoneHandle(I, node->field().type()); |
| 3178 const String& dst_name = String::ZoneHandle(I, node->field().name()); |
| 3170 store_value = BuildAssignableValue(node->value()->token_pos(), | 3179 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 3171 store_value, | 3180 store_value, |
| 3172 type, | 3181 type, |
| 3173 dst_name); | 3182 dst_name); |
| 3174 } | 3183 } |
| 3175 | 3184 |
| 3176 store_value = Bind(BuildStoreExprTemp(store_value)); | 3185 store_value = Bind(BuildStoreExprTemp(store_value)); |
| 3177 GuardFieldInstr* guard = | 3186 GuardFieldInstr* guard = |
| 3178 new GuardFieldInstr(store_value, | 3187 new GuardFieldInstr(store_value, node->field(), I->GetNextDeoptId()); |
| 3179 node->field(), | |
| 3180 Isolate::Current()->GetNextDeoptId()); | |
| 3181 AddInstruction(guard); | 3188 AddInstruction(guard); |
| 3182 | 3189 |
| 3183 store_value = Bind(BuildLoadExprTemp()); | 3190 store_value = Bind(BuildLoadExprTemp()); |
| 3184 StoreInstanceFieldInstr* store = | 3191 StoreInstanceFieldInstr* store = |
| 3185 new StoreInstanceFieldInstr(node->field(), | 3192 new StoreInstanceFieldInstr(node->field(), |
| 3186 for_instance.value(), | 3193 for_instance.value(), |
| 3187 store_value, | 3194 store_value, |
| 3188 kEmitStoreBarrier, | 3195 kEmitStoreBarrier, |
| 3189 node->token_pos()); | 3196 node->token_pos()); |
| 3190 store->set_is_initialization(true); // Maybe initializing store. | 3197 store->set_is_initialization(true); // Maybe initializing store. |
| 3191 ReturnDefinition(store); | 3198 ReturnDefinition(store); |
| 3192 } | 3199 } |
| 3193 | 3200 |
| 3194 | 3201 |
| 3195 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 3202 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 3196 if (node->field().is_const()) { | 3203 if (node->field().is_const()) { |
| 3197 ASSERT(node->field().value() != Object::sentinel().raw()); | 3204 ASSERT(node->field().value() != Object::sentinel().raw()); |
| 3198 ASSERT(node->field().value() != Object::transition_sentinel().raw()); | 3205 ASSERT(node->field().value() != Object::transition_sentinel().raw()); |
| 3199 Definition* result = | 3206 Definition* result = |
| 3200 new ConstantInstr(Instance::ZoneHandle(node->field().value())); | 3207 new ConstantInstr(Instance::ZoneHandle(I, node->field().value())); |
| 3201 return ReturnDefinition(result); | 3208 return ReturnDefinition(result); |
| 3202 } | 3209 } |
| 3203 Value* field_value = Bind(new ConstantInstr(node->field())); | 3210 Value* field_value = Bind(new ConstantInstr(node->field())); |
| 3204 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(field_value); | 3211 LoadStaticFieldInstr* load = new LoadStaticFieldInstr(field_value); |
| 3205 ReturnDefinition(load); | 3212 ReturnDefinition(load); |
| 3206 } | 3213 } |
| 3207 | 3214 |
| 3208 | 3215 |
| 3209 Definition* EffectGraphVisitor::BuildStoreStaticField( | 3216 Definition* EffectGraphVisitor::BuildStoreStaticField( |
| 3210 StoreStaticFieldNode* node, bool result_is_needed) { | 3217 StoreStaticFieldNode* node, bool result_is_needed) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 3237 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 3244 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 3238 ReturnDefinition(BuildStoreStaticField(node, kResultNeeded)); | 3245 ReturnDefinition(BuildStoreStaticField(node, kResultNeeded)); |
| 3239 } | 3246 } |
| 3240 | 3247 |
| 3241 | 3248 |
| 3242 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { | 3249 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) { |
| 3243 Function* super_function = NULL; | 3250 Function* super_function = NULL; |
| 3244 if (node->IsSuperLoad()) { | 3251 if (node->IsSuperLoad()) { |
| 3245 // Resolve the load indexed operator in the super class. | 3252 // Resolve the load indexed operator in the super class. |
| 3246 super_function = &Function::ZoneHandle( | 3253 super_function = &Function::ZoneHandle( |
| 3247 Resolver::ResolveDynamicAnyArgs(node->super_class(), | 3254 I, Resolver::ResolveDynamicAnyArgs(node->super_class(), |
| 3248 Symbols::IndexToken())); | 3255 Symbols::IndexToken())); |
| 3249 if (super_function->IsNull()) { | 3256 if (super_function->IsNull()) { |
| 3250 // Could not resolve super operator. Generate call noSuchMethod() of the | 3257 // Could not resolve super operator. Generate call noSuchMethod() of the |
| 3251 // super class instead. | 3258 // super class instead. |
| 3252 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); | 3259 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); |
| 3253 arguments->Add(node->array()); | 3260 arguments->Add(node->array()); |
| 3254 arguments->Add(node->index_expr()); | 3261 arguments->Add(node->index_expr()); |
| 3255 StaticCallInstr* call = | 3262 StaticCallInstr* call = |
| 3256 BuildStaticNoSuchMethodCall(node->super_class(), | 3263 BuildStaticNoSuchMethodCall(node->super_class(), |
| 3257 node->array(), | 3264 node->array(), |
| 3258 Symbols::IndexToken(), | 3265 Symbols::IndexToken(), |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3298 } | 3305 } |
| 3299 | 3306 |
| 3300 | 3307 |
| 3301 Definition* EffectGraphVisitor::BuildStoreIndexedValues( | 3308 Definition* EffectGraphVisitor::BuildStoreIndexedValues( |
| 3302 StoreIndexedNode* node, | 3309 StoreIndexedNode* node, |
| 3303 bool result_is_needed) { | 3310 bool result_is_needed) { |
| 3304 Function* super_function = NULL; | 3311 Function* super_function = NULL; |
| 3305 if (node->IsSuperStore()) { | 3312 if (node->IsSuperStore()) { |
| 3306 // Resolve the store indexed operator in the super class. | 3313 // Resolve the store indexed operator in the super class. |
| 3307 super_function = &Function::ZoneHandle( | 3314 super_function = &Function::ZoneHandle( |
| 3308 Resolver::ResolveDynamicAnyArgs(node->super_class(), | 3315 I, Resolver::ResolveDynamicAnyArgs(node->super_class(), |
| 3309 Symbols::AssignIndexToken())); | 3316 Symbols::AssignIndexToken())); |
| 3310 if (super_function->IsNull()) { | 3317 if (super_function->IsNull()) { |
| 3311 // Could not resolve super operator. Generate call noSuchMethod() of the | 3318 // Could not resolve super operator. Generate call noSuchMethod() of the |
| 3312 // super class instead. | 3319 // super class instead. |
| 3313 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); | 3320 ArgumentListNode* arguments = new ArgumentListNode(node->token_pos()); |
| 3314 arguments->Add(node->array()); | 3321 arguments->Add(node->array()); |
| 3315 arguments->Add(node->index_expr()); | 3322 arguments->Add(node->index_expr()); |
| 3316 arguments->Add(node->value()); | 3323 arguments->Add(node->value()); |
| 3317 StaticCallInstr* call = BuildStaticNoSuchMethodCall( | 3324 StaticCallInstr* call = BuildStaticNoSuchMethodCall( |
| 3318 node->super_class(), | 3325 node->super_class(), |
| 3319 node->array(), | 3326 node->array(), |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3366 if (result_is_needed) { | 3373 if (result_is_needed) { |
| 3367 Do(store); | 3374 Do(store); |
| 3368 return BuildLoadExprTemp(); | 3375 return BuildLoadExprTemp(); |
| 3369 } else { | 3376 } else { |
| 3370 return store; | 3377 return store; |
| 3371 } | 3378 } |
| 3372 } else { | 3379 } else { |
| 3373 // Generate dynamic call to operator []=. | 3380 // Generate dynamic call to operator []=. |
| 3374 const intptr_t checked_argument_count = 3; | 3381 const intptr_t checked_argument_count = 3; |
| 3375 const String& name = | 3382 const String& name = |
| 3376 String::ZoneHandle(Symbols::New(Token::Str(Token::kASSIGN_INDEX))); | 3383 String::ZoneHandle(I, Symbols::New(Token::Str(Token::kASSIGN_INDEX))); |
| 3377 InstanceCallInstr* store = | 3384 InstanceCallInstr* store = |
| 3378 new InstanceCallInstr(node->token_pos(), | 3385 new InstanceCallInstr(node->token_pos(), |
| 3379 name, | 3386 name, |
| 3380 Token::kASSIGN_INDEX, | 3387 Token::kASSIGN_INDEX, |
| 3381 arguments, | 3388 arguments, |
| 3382 Object::null_array(), | 3389 Object::null_array(), |
| 3383 checked_argument_count, | 3390 checked_argument_count, |
| 3384 owner()->ic_data_array()); | 3391 owner()->ic_data_array()); |
| 3385 if (result_is_needed) { | 3392 if (result_is_needed) { |
| 3386 Do(store); | 3393 Do(store); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3408 } | 3415 } |
| 3409 | 3416 |
| 3410 | 3417 |
| 3411 void EffectGraphVisitor::UnchainContexts(intptr_t n) { | 3418 void EffectGraphVisitor::UnchainContexts(intptr_t n) { |
| 3412 if (n > 0) { | 3419 if (n > 0) { |
| 3413 Value* context = Bind(new CurrentContextInstr()); | 3420 Value* context = Bind(new CurrentContextInstr()); |
| 3414 while (n-- > 0) { | 3421 while (n-- > 0) { |
| 3415 context = Bind( | 3422 context = Bind( |
| 3416 new LoadFieldInstr(context, | 3423 new LoadFieldInstr(context, |
| 3417 Context::parent_offset(), | 3424 Context::parent_offset(), |
| 3418 Type::ZoneHandle(), // Not an instance, no type. | 3425 // Not an instance, no type. |
| 3426 Type::ZoneHandle(I, Type::null()), |
| 3419 Scanner::kNoSourcePos)); | 3427 Scanner::kNoSourcePos)); |
| 3420 } | 3428 } |
| 3421 AddInstruction(new StoreContextInstr(context)); | 3429 AddInstruction(new StoreContextInstr(context)); |
| 3422 } | 3430 } |
| 3423 } | 3431 } |
| 3424 | 3432 |
| 3425 | 3433 |
| 3426 // <Statement> ::= Sequence { scope: LocalScope | 3434 // <Statement> ::= Sequence { scope: LocalScope |
| 3427 // nodes: <Statement>* | 3435 // nodes: <Statement>* |
| 3428 // label: SourceLabel } | 3436 // label: SourceLabel } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3447 // if this function allocates context variables, but none of its enclosing | 3455 // if this function allocates context variables, but none of its enclosing |
| 3448 // functions do, the context on entry is not linked as parent of the | 3456 // functions do, the context on entry is not linked as parent of the |
| 3449 // allocated context but saved on entry and restored on exit as to prevent | 3457 // allocated context but saved on entry and restored on exit as to prevent |
| 3450 // memory leaks. | 3458 // memory leaks. |
| 3451 // In this case, the parser pre-allocates a variable to save the context. | 3459 // In this case, the parser pre-allocates a variable to save the context. |
| 3452 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var)); | 3460 Value* tmp_val = Bind(new LoadLocalInstr(*tmp_var)); |
| 3453 Value* parent_context = NULL; | 3461 Value* parent_context = NULL; |
| 3454 if (MustSaveRestoreContext(node)) { | 3462 if (MustSaveRestoreContext(node)) { |
| 3455 BuildSaveContext( | 3463 BuildSaveContext( |
| 3456 *owner()->parsed_function()->saved_entry_context_var()); | 3464 *owner()->parsed_function()->saved_entry_context_var()); |
| 3457 parent_context = Bind(new ConstantInstr(Object::ZoneHandle())); | 3465 parent_context = Bind( |
| 3466 new ConstantInstr(Object::ZoneHandle(I, Object::null()))); |
| 3458 } else { | 3467 } else { |
| 3459 parent_context = Bind(new CurrentContextInstr()); | 3468 parent_context = Bind(new CurrentContextInstr()); |
| 3460 } | 3469 } |
| 3461 Do(new StoreInstanceFieldInstr(Context::parent_offset(), | 3470 Do(new StoreInstanceFieldInstr(Context::parent_offset(), |
| 3462 tmp_val, | 3471 tmp_val, |
| 3463 parent_context, | 3472 parent_context, |
| 3464 kEmitStoreBarrier, | 3473 kEmitStoreBarrier, |
| 3465 Scanner::kNoSourcePos)); | 3474 Scanner::kNoSourcePos)); |
| 3466 AddInstruction( | 3475 AddInstruction( |
| 3467 new StoreContextInstr(Bind(ExitTempLocalScope(tmp_var)))); | 3476 new StoreContextInstr(Bind(ExitTempLocalScope(tmp_var)))); |
| 3468 } | 3477 } |
| 3469 | 3478 |
| 3470 // If this node_sequence is the body of the function being compiled, copy | 3479 // If this node_sequence is the body of the function being compiled, copy |
| 3471 // the captured parameters from the frame into the context. | 3480 // the captured parameters from the frame into the context. |
| 3472 if (node == owner()->parsed_function()->node_sequence()) { | 3481 if (node == owner()->parsed_function()->node_sequence()) { |
| 3473 ASSERT(scope->context_level() == 1); | 3482 ASSERT(scope->context_level() == 1); |
| 3474 const Function& function = owner()->parsed_function()->function(); | 3483 const Function& function = owner()->parsed_function()->function(); |
| 3475 const int num_params = function.NumParameters(); | 3484 const int num_params = function.NumParameters(); |
| 3476 int param_frame_index = (num_params == function.num_fixed_parameters()) ? | 3485 int param_frame_index = (num_params == function.num_fixed_parameters()) ? |
| 3477 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; | 3486 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; |
| 3478 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { | 3487 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { |
| 3479 const LocalVariable& parameter = *scope->VariableAt(pos); | 3488 const LocalVariable& parameter = *scope->VariableAt(pos); |
| 3480 ASSERT(parameter.owner() == scope); | 3489 ASSERT(parameter.owner() == scope); |
| 3481 if (parameter.is_captured()) { | 3490 if (parameter.is_captured()) { |
| 3482 // Create a temporary local describing the original position. | 3491 // Create a temporary local describing the original position. |
| 3483 const String& temp_name = Symbols::TempParam(); | 3492 const String& temp_name = Symbols::TempParam(); |
| 3484 LocalVariable* temp_local = new LocalVariable( | 3493 LocalVariable* temp_local = new LocalVariable( |
| 3485 0, // Token index. | 3494 0, // Token index. |
| 3486 temp_name, | 3495 temp_name, |
| 3487 Type::ZoneHandle(Type::DynamicType())); // Type. | 3496 Type::ZoneHandle(I, Type::DynamicType())); // Type. |
| 3488 temp_local->set_index(param_frame_index); | 3497 temp_local->set_index(param_frame_index); |
| 3489 | 3498 |
| 3490 // Copy parameter from local frame to current context. | 3499 // Copy parameter from local frame to current context. |
| 3491 Value* load = Bind(BuildLoadLocal(*temp_local)); | 3500 Value* load = Bind(BuildLoadLocal(*temp_local)); |
| 3492 Do(BuildStoreLocal(parameter, load)); | 3501 Do(BuildStoreLocal(parameter, load)); |
| 3493 // Write NULL to the source location to detect buggy accesses and | 3502 // Write NULL to the source location to detect buggy accesses and |
| 3494 // allow GC of passed value if it gets overwritten by a new value in | 3503 // allow GC of passed value if it gets overwritten by a new value in |
| 3495 // the function. | 3504 // the function. |
| 3496 Value* null_constant = | 3505 Value* null_constant = Bind(new ConstantInstr( |
| 3497 Bind(new ConstantInstr(Object::ZoneHandle())); | 3506 Object::ZoneHandle(I, Object::null()))); |
| 3498 Do(BuildStoreLocal(*temp_local, null_constant)); | 3507 Do(BuildStoreLocal(*temp_local, null_constant)); |
| 3499 } | 3508 } |
| 3500 } | 3509 } |
| 3501 } | 3510 } |
| 3502 } else if (MustSaveRestoreContext(node)) { | 3511 } else if (MustSaveRestoreContext(node)) { |
| 3503 // Even when the current scope has no context variables, we may | 3512 // Even when the current scope has no context variables, we may |
| 3504 // still need to save the current context if, for example, there | 3513 // still need to save the current context if, for example, there |
| 3505 // are loop scopes below this which will allocate a context | 3514 // are loop scopes below this which will allocate a context |
| 3506 // object. | 3515 // object. |
| 3507 BuildSaveContext( | 3516 BuildSaveContext( |
| 3508 *owner()->parsed_function()->saved_entry_context_var()); | 3517 *owner()->parsed_function()->saved_entry_context_var()); |
| 3509 AddInstruction( | 3518 AddInstruction( |
| 3510 new StoreContextInstr(Bind(new ConstantInstr(Object::ZoneHandle( | 3519 new StoreContextInstr(Bind(new ConstantInstr(Object::ZoneHandle( |
| 3511 Isolate::Current()->object_store()->empty_context()))))); | 3520 I, I->object_store()->empty_context()))))); |
| 3512 } | 3521 } |
| 3513 | 3522 |
| 3514 // This check may be deleted if the generated code is leaf. | 3523 // This check may be deleted if the generated code is leaf. |
| 3515 // Native functions don't need a stack check at entry. | 3524 // Native functions don't need a stack check at entry. |
| 3516 const Function& function = owner()->parsed_function()->function(); | 3525 const Function& function = owner()->parsed_function()->function(); |
| 3517 if ((node == owner()->parsed_function()->node_sequence()) && | 3526 if ((node == owner()->parsed_function()->node_sequence()) && |
| 3518 !function.is_native()) { | 3527 !function.is_native()) { |
| 3519 // Always allocate CheckOverflowInstr so that deopt-ids match regardless | 3528 // Always allocate CheckOverflowInstr so that deopt-ids match regardless |
| 3520 // if we inline or not. | 3529 // if we inline or not. |
| 3521 if (!function.IsImplicitGetterFunction() && | 3530 if (!function.IsImplicitGetterFunction() && |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3692 for_finally.PushArgument(exception); | 3701 for_finally.PushArgument(exception); |
| 3693 Value* stacktrace = for_finally.Bind( | 3702 Value* stacktrace = for_finally.Bind( |
| 3694 for_finally.BuildLoadLocal(catch_block->stacktrace_var())); | 3703 for_finally.BuildLoadLocal(catch_block->stacktrace_var())); |
| 3695 for_finally.PushArgument(stacktrace); | 3704 for_finally.PushArgument(stacktrace); |
| 3696 for_finally.AddInstruction( | 3705 for_finally.AddInstruction( |
| 3697 new ReThrowInstr(catch_block->token_pos(), catch_handler_index)); | 3706 new ReThrowInstr(catch_block->token_pos(), catch_handler_index)); |
| 3698 for_finally.CloseFragment(); | 3707 for_finally.CloseFragment(); |
| 3699 } | 3708 } |
| 3700 ASSERT(!for_finally.is_open()); | 3709 ASSERT(!for_finally.is_open()); |
| 3701 | 3710 |
| 3702 const Array& types = Array::ZoneHandle(Array::New(1, Heap::kOld)); | 3711 const Array& types = Array::ZoneHandle(I, Array::New(1, Heap::kOld)); |
| 3703 types.SetAt(0, Type::Handle(Type::DynamicType())); | 3712 types.SetAt(0, Type::Handle(I, Type::DynamicType())); |
| 3704 CatchBlockEntryInstr* finally_entry = | 3713 CatchBlockEntryInstr* finally_entry = |
| 3705 new CatchBlockEntryInstr(owner()->AllocateBlockId(), | 3714 new CatchBlockEntryInstr(owner()->AllocateBlockId(), |
| 3706 original_handler_index, | 3715 original_handler_index, |
| 3707 types, | 3716 types, |
| 3708 catch_handler_index, | 3717 catch_handler_index, |
| 3709 catch_block->exception_var(), | 3718 catch_block->exception_var(), |
| 3710 catch_block->stacktrace_var(), | 3719 catch_block->stacktrace_var(), |
| 3711 catch_block->needs_stacktrace()); | 3720 catch_block->needs_stacktrace()); |
| 3712 owner()->AddCatchEntry(finally_entry); | 3721 owner()->AddCatchEntry(finally_entry); |
| 3713 AppendFragment(finally_entry, for_finally); | 3722 AppendFragment(finally_entry, for_finally); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3736 if (save_last_arg) { | 3745 if (save_last_arg) { |
| 3737 temp = owner()->parsed_function()->EnsureExpressionTemp(); | 3746 temp = owner()->parsed_function()->EnsureExpressionTemp(); |
| 3738 } | 3747 } |
| 3739 ArgumentListNode* args = | 3748 ArgumentListNode* args = |
| 3740 Parser::BuildNoSuchMethodArguments(args_pos, | 3749 Parser::BuildNoSuchMethodArguments(args_pos, |
| 3741 method_name, | 3750 method_name, |
| 3742 *method_arguments, | 3751 *method_arguments, |
| 3743 temp, | 3752 temp, |
| 3744 is_super_invocation); | 3753 is_super_invocation); |
| 3745 const Function& no_such_method_func = Function::ZoneHandle( | 3754 const Function& no_such_method_func = Function::ZoneHandle( |
| 3755 I, |
| 3746 Resolver::ResolveDynamicAnyArgs(target_class, Symbols::NoSuchMethod())); | 3756 Resolver::ResolveDynamicAnyArgs(target_class, Symbols::NoSuchMethod())); |
| 3747 // We are guaranteed to find noSuchMethod of class Object. | 3757 // We are guaranteed to find noSuchMethod of class Object. |
| 3748 ASSERT(!no_such_method_func.IsNull()); | 3758 ASSERT(!no_such_method_func.IsNull()); |
| 3749 ZoneGrowableArray<PushArgumentInstr*>* push_arguments = | 3759 ZoneGrowableArray<PushArgumentInstr*>* push_arguments = |
| 3750 new ZoneGrowableArray<PushArgumentInstr*>(2); | 3760 new ZoneGrowableArray<PushArgumentInstr*>(2); |
| 3751 BuildPushArguments(*args, push_arguments); | 3761 BuildPushArguments(*args, push_arguments); |
| 3752 return new StaticCallInstr(args_pos, | 3762 return new StaticCallInstr(args_pos, |
| 3753 no_such_method_func, | 3763 no_such_method_func, |
| 3754 Object::null_array(), | 3764 Object::null_array(), |
| 3755 push_arguments, | 3765 push_arguments, |
| 3756 owner()->ic_data_array()); | 3766 owner()->ic_data_array()); |
| 3757 } | 3767 } |
| 3758 | 3768 |
| 3759 | 3769 |
| 3760 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( | 3770 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError( |
| 3761 intptr_t token_pos, | 3771 intptr_t token_pos, |
| 3762 const Class& function_class, | 3772 const Class& function_class, |
| 3763 const String& function_name, | 3773 const String& function_name, |
| 3764 ArgumentListNode* function_arguments, | 3774 ArgumentListNode* function_arguments, |
| 3765 int invocation_type) { | 3775 int invocation_type) { |
| 3766 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 3776 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 3767 new ZoneGrowableArray<PushArgumentInstr*>(); | 3777 new ZoneGrowableArray<PushArgumentInstr*>(); |
| 3768 // Object receiver. | 3778 // Object receiver. |
| 3769 // TODO(regis): For now, we pass a class literal of the unresolved | 3779 // TODO(regis): For now, we pass a class literal of the unresolved |
| 3770 // method's owner, but this is not specified and will probably change. | 3780 // method's owner, but this is not specified and will probably change. |
| 3771 Type& type = Type::ZoneHandle( | 3781 Type& type = Type::ZoneHandle( |
| 3782 I, |
| 3772 Type::New(function_class, | 3783 Type::New(function_class, |
| 3773 TypeArguments::Handle(), | 3784 TypeArguments::Handle(I, TypeArguments::null()), |
| 3774 token_pos, | 3785 token_pos, |
| 3775 Heap::kOld)); | 3786 Heap::kOld)); |
| 3776 type ^= ClassFinalizer::FinalizeType( | 3787 type ^= ClassFinalizer::FinalizeType( |
| 3777 function_class, type, ClassFinalizer::kCanonicalize); | 3788 function_class, type, ClassFinalizer::kCanonicalize); |
| 3778 Value* receiver_value = Bind(new ConstantInstr(type)); | 3789 Value* receiver_value = Bind(new ConstantInstr(type)); |
| 3779 arguments->Add(PushArgument(receiver_value)); | 3790 arguments->Add(PushArgument(receiver_value)); |
| 3780 // String memberName. | 3791 // String memberName. |
| 3781 const String& member_name = String::ZoneHandle(Symbols::New(function_name)); | 3792 const String& member_name = |
| 3793 String::ZoneHandle(I, Symbols::New(function_name)); |
| 3782 Value* member_name_value = Bind(new ConstantInstr(member_name)); | 3794 Value* member_name_value = Bind(new ConstantInstr(member_name)); |
| 3783 arguments->Add(PushArgument(member_name_value)); | 3795 arguments->Add(PushArgument(member_name_value)); |
| 3784 // Smi invocation_type. | 3796 // Smi invocation_type. |
| 3785 Value* invocation_type_value = Bind(new ConstantInstr( | 3797 Value* invocation_type_value = Bind(new ConstantInstr( |
| 3786 Smi::ZoneHandle(Smi::New(invocation_type)))); | 3798 Smi::ZoneHandle(I, Smi::New(invocation_type)))); |
| 3787 arguments->Add(PushArgument(invocation_type_value)); | 3799 arguments->Add(PushArgument(invocation_type_value)); |
| 3788 // List arguments. | 3800 // List arguments. |
| 3789 if (function_arguments == NULL) { | 3801 if (function_arguments == NULL) { |
| 3790 Value* arguments_value = Bind(new ConstantInstr(Array::ZoneHandle())); | 3802 Value* arguments_value = Bind( |
| 3803 new ConstantInstr(Array::ZoneHandle(I, Array::null()))); |
| 3791 arguments->Add(PushArgument(arguments_value)); | 3804 arguments->Add(PushArgument(arguments_value)); |
| 3792 } else { | 3805 } else { |
| 3793 ValueGraphVisitor array_val(owner()); | 3806 ValueGraphVisitor array_val(owner()); |
| 3794 ArrayNode* array = | 3807 ArrayNode* array = |
| 3795 new ArrayNode(token_pos, Type::ZoneHandle(Type::ArrayType()), | 3808 new ArrayNode(token_pos, Type::ZoneHandle(I, Type::ArrayType()), |
| 3796 function_arguments->nodes()); | 3809 function_arguments->nodes()); |
| 3797 array->Visit(&array_val); | 3810 array->Visit(&array_val); |
| 3798 Append(array_val); | 3811 Append(array_val); |
| 3799 arguments->Add(PushArgument(array_val.value())); | 3812 arguments->Add(PushArgument(array_val.value())); |
| 3800 } | 3813 } |
| 3801 // List argumentNames. | 3814 // List argumentNames. |
| 3802 ConstantInstr* cinstr = new ConstantInstr( | 3815 ConstantInstr* cinstr = new ConstantInstr( |
| 3803 (function_arguments == NULL) ? Array::ZoneHandle() | 3816 (function_arguments == NULL) ? Array::ZoneHandle(I, Array::null()) |
| 3804 : function_arguments->names()); | 3817 : function_arguments->names()); |
| 3805 Value* argument_names_value = Bind(cinstr); | 3818 Value* argument_names_value = Bind(cinstr); |
| 3806 arguments->Add(PushArgument(argument_names_value)); | 3819 arguments->Add(PushArgument(argument_names_value)); |
| 3807 | 3820 |
| 3808 // List existingArgumentNames. | 3821 // List existingArgumentNames. |
| 3809 Value* existing_argument_names_value = | 3822 Value* existing_argument_names_value = |
| 3810 Bind(new ConstantInstr(Array::ZoneHandle())); | 3823 Bind(new ConstantInstr(Array::ZoneHandle(I, Array::null()))); |
| 3811 arguments->Add(PushArgument(existing_argument_names_value)); | 3824 arguments->Add(PushArgument(existing_argument_names_value)); |
| 3812 // Resolve and call NoSuchMethodError._throwNew. | 3825 // Resolve and call NoSuchMethodError._throwNew. |
| 3813 const Library& core_lib = Library::Handle(Library::CoreLibrary()); | 3826 const Library& core_lib = Library::Handle(I, Library::CoreLibrary()); |
| 3814 const Class& cls = Class::Handle( | 3827 const Class& cls = Class::Handle( |
| 3815 core_lib.LookupClass(Symbols::NoSuchMethodError())); | 3828 I, core_lib.LookupClass(Symbols::NoSuchMethodError())); |
| 3816 ASSERT(!cls.IsNull()); | 3829 ASSERT(!cls.IsNull()); |
| 3817 const Function& func = Function::ZoneHandle( | 3830 const Function& func = Function::ZoneHandle( |
| 3831 I, |
| 3818 Resolver::ResolveStatic(cls, | 3832 Resolver::ResolveStatic(cls, |
| 3819 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 3833 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 3820 arguments->length(), | 3834 arguments->length(), |
| 3821 Object::null_array())); | 3835 Object::null_array())); |
| 3822 ASSERT(!func.IsNull()); | 3836 ASSERT(!func.IsNull()); |
| 3823 return new StaticCallInstr(token_pos, | 3837 return new StaticCallInstr(token_pos, |
| 3824 func, | 3838 func, |
| 3825 Object::null_array(), // No names. | 3839 Object::null_array(), // No names. |
| 3826 arguments, | 3840 arguments, |
| 3827 owner()->ic_data_array()); | 3841 owner()->ic_data_array()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3851 BuildThrowNode(node); | 3865 BuildThrowNode(node); |
| 3852 CloseFragment(); | 3866 CloseFragment(); |
| 3853 } | 3867 } |
| 3854 | 3868 |
| 3855 | 3869 |
| 3856 // A throw cannot be part of an expression, however, the parser may replace | 3870 // A throw cannot be part of an expression, however, the parser may replace |
| 3857 // certain expression nodes with a throw. In that case generate a literal null | 3871 // certain expression nodes with a throw. In that case generate a literal null |
| 3858 // so that the fragment is not closed in the middle of an expression. | 3872 // so that the fragment is not closed in the middle of an expression. |
| 3859 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { | 3873 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) { |
| 3860 BuildThrowNode(node); | 3874 BuildThrowNode(node); |
| 3861 ReturnDefinition(new ConstantInstr(Instance::ZoneHandle())); | 3875 ReturnDefinition(new ConstantInstr( |
| 3876 Instance::ZoneHandle(I, Instance::null()))); |
| 3862 } | 3877 } |
| 3863 | 3878 |
| 3864 | 3879 |
| 3865 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { | 3880 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { |
| 3866 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode (exception)"); | 3881 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode (exception)"); |
| 3867 const intptr_t try_index = owner()->try_index(); | 3882 const intptr_t try_index = owner()->try_index(); |
| 3868 if (try_index >= 0) { | 3883 if (try_index >= 0) { |
| 3869 // We are about to generate code for an inlined finally block. Exceptions | 3884 // We are about to generate code for an inlined finally block. Exceptions |
| 3870 // thrown in this block of code should be treated as though they are | 3885 // thrown in this block of code should be treated as though they are |
| 3871 // thrown not from the current try block but the outer try block if any. | 3886 // thrown not from the current try block but the outer try block if any. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3938 } | 3953 } |
| 3939 | 3954 |
| 3940 | 3955 |
| 3941 void FlowGraphBuilder::Warning(intptr_t token_pos, | 3956 void FlowGraphBuilder::Warning(intptr_t token_pos, |
| 3942 const char* format, ...) const { | 3957 const char* format, ...) const { |
| 3943 if (FLAG_silent_warnings) return; | 3958 if (FLAG_silent_warnings) return; |
| 3944 const Function& function = parsed_function_->function(); | 3959 const Function& function = parsed_function_->function(); |
| 3945 va_list args; | 3960 va_list args; |
| 3946 va_start(args, format); | 3961 va_start(args, format); |
| 3947 const Error& error = Error::Handle( | 3962 const Error& error = Error::Handle( |
| 3948 LanguageError::NewFormattedV(Error::Handle(), // No previous error. | 3963 I, |
| 3949 Script::Handle(function.script()), | 3964 LanguageError::NewFormattedV( |
| 3950 token_pos, LanguageError::kWarning, | 3965 Error::Handle(I, Error::null()), // No previous error. |
| 3951 Heap::kNew, format, args)); | 3966 Script::Handle(I, function.script()), |
| 3967 token_pos, LanguageError::kWarning, |
| 3968 Heap::kNew, format, args)); |
| 3952 va_end(args); | 3969 va_end(args); |
| 3953 if (FLAG_warning_as_error) { | 3970 if (FLAG_warning_as_error) { |
| 3954 Isolate::Current()->long_jump_base()->Jump(1, error); | 3971 I->long_jump_base()->Jump(1, error); |
| 3955 UNREACHABLE(); | 3972 UNREACHABLE(); |
| 3956 } else { | 3973 } else { |
| 3957 OS::Print("%s", error.ToErrorCString()); | 3974 OS::Print("%s", error.ToErrorCString()); |
| 3958 } | 3975 } |
| 3959 } | 3976 } |
| 3960 | 3977 |
| 3961 | 3978 |
| 3962 void FlowGraphBuilder::Bailout(const char* reason) const { | 3979 void FlowGraphBuilder::Bailout(const char* reason) const { |
| 3963 const Function& function = parsed_function_->function(); | 3980 const Function& function = parsed_function_->function(); |
| 3964 const Error& error = Error::Handle( | 3981 const Error& error = Error::Handle( |
| 3965 LanguageError::NewFormatted(Error::Handle(), // No previous error. | 3982 I, |
| 3966 Script::Handle(function.script()), | 3983 LanguageError::NewFormatted( |
| 3967 function.token_pos(), | 3984 Error::Handle(I, Error::null()), // No previous error. |
| 3968 LanguageError::kBailout, | 3985 Script::Handle(I, function.script()), |
| 3969 Heap::kNew, | 3986 function.token_pos(), |
| 3970 "FlowGraphBuilder Bailout: %s %s", | 3987 LanguageError::kBailout, |
| 3971 String::Handle(function.name()).ToCString(), | 3988 Heap::kNew, |
| 3972 reason)); | 3989 "FlowGraphBuilder Bailout: %s %s", |
| 3973 Isolate::Current()->long_jump_base()->Jump(1, error); | 3990 String::Handle(I, function.name()).ToCString(), |
| 3991 reason)); |
| 3992 I->long_jump_base()->Jump(1, error); |
| 3974 UNREACHABLE(); | 3993 UNREACHABLE(); |
| 3975 } | 3994 } |
| 3976 | 3995 |
| 3977 } // namespace dart | 3996 } // namespace dart |
| OLD | NEW |