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 |