OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1044 | 1044 |
1045 | 1045 |
1046 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, | 1046 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, |
1047 Handle<Map> map) { | 1047 Handle<Map> map) { |
1048 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); | 1048 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); |
1049 AddInstruction(check); | 1049 AddInstruction(check); |
1050 return check; | 1050 return check; |
1051 } | 1051 } |
1052 | 1052 |
1053 | 1053 |
1054 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( | |
1055 HValue* external_elements, | |
1056 HValue* checked_key, | |
1057 HValue* val, | |
1058 HValue* dependency, | |
1059 ElementsKind elements_kind, | |
1060 bool is_store) { | |
1061 Zone* zone = this->zone(); | |
1062 if (is_store) { | |
1063 ASSERT(val != NULL); | |
1064 switch (elements_kind) { | |
1065 case EXTERNAL_PIXEL_ELEMENTS: { | |
1066 val = Add<HClampToUint8>(val); | |
1067 break; | |
1068 } | |
1069 case EXTERNAL_BYTE_ELEMENTS: | |
1070 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | |
1071 case EXTERNAL_SHORT_ELEMENTS: | |
1072 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | |
1073 case EXTERNAL_INT_ELEMENTS: | |
1074 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { | |
1075 break; | |
1076 } | |
1077 case EXTERNAL_FLOAT_ELEMENTS: | |
1078 case EXTERNAL_DOUBLE_ELEMENTS: | |
1079 break; | |
1080 case FAST_SMI_ELEMENTS: | |
1081 case FAST_ELEMENTS: | |
1082 case FAST_DOUBLE_ELEMENTS: | |
1083 case FAST_HOLEY_SMI_ELEMENTS: | |
1084 case FAST_HOLEY_ELEMENTS: | |
1085 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
1086 case DICTIONARY_ELEMENTS: | |
1087 case NON_STRICT_ARGUMENTS_ELEMENTS: | |
1088 UNREACHABLE(); | |
1089 break; | |
1090 } | |
1091 return new(zone) HStoreKeyed(external_elements, checked_key, | |
1092 val, elements_kind); | |
1093 } else { | |
1094 ASSERT(val == NULL); | |
1095 HLoadKeyed* load = | |
1096 new(zone) HLoadKeyed( | |
1097 external_elements, checked_key, dependency, elements_kind); | |
1098 if (FLAG_opt_safe_uint32_operations && | |
1099 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { | |
1100 graph()->RecordUint32Instruction(load); | |
1101 } | |
1102 return load; | |
1103 } | |
1104 } | |
1105 | |
1106 | |
1107 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, | 1054 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, |
1108 HValue* elements, | 1055 HValue* elements, |
1109 ElementsKind kind, | 1056 ElementsKind kind, |
1110 HValue* length, | 1057 HValue* length, |
1111 HValue* key, | 1058 HValue* key, |
1112 bool is_js_array) { | 1059 bool is_js_array) { |
1113 Zone* zone = this->zone(); | 1060 Zone* zone = this->zone(); |
1114 IfBuilder length_checker(this); | 1061 IfBuilder length_checker(this); |
1115 | 1062 |
1116 Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ; | 1063 Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ; |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1279 NoObservableSideEffectsScope no_effects(this); | 1226 NoObservableSideEffectsScope no_effects(this); |
1280 HLoadExternalArrayPointer* external_elements = | 1227 HLoadExternalArrayPointer* external_elements = |
1281 Add<HLoadExternalArrayPointer>(elements); | 1228 Add<HLoadExternalArrayPointer>(elements); |
1282 IfBuilder length_checker(this); | 1229 IfBuilder length_checker(this); |
1283 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); | 1230 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); |
1284 length_checker.Then(); | 1231 length_checker.Then(); |
1285 IfBuilder negative_checker(this); | 1232 IfBuilder negative_checker(this); |
1286 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( | 1233 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( |
1287 key, graph()->GetConstant0(), Token::GTE); | 1234 key, graph()->GetConstant0(), Token::GTE); |
1288 negative_checker.Then(); | 1235 negative_checker.Then(); |
1289 HInstruction* result = BuildExternalArrayElementAccess( | 1236 HInstruction* result = AddExternalArrayElementAccess( |
1290 external_elements, key, val, bounds_check, | 1237 external_elements, key, val, bounds_check, elements_kind, is_store); |
1291 elements_kind, is_store); | |
1292 AddInstruction(result); | |
1293 negative_checker.ElseDeopt(); | 1238 negative_checker.ElseDeopt(); |
1294 length_checker.End(); | 1239 length_checker.End(); |
1295 return result; | 1240 return result; |
1296 } else { | 1241 } else { |
1297 ASSERT(store_mode == STANDARD_STORE); | 1242 ASSERT(store_mode == STANDARD_STORE); |
1298 checked_key = Add<HBoundsCheck>(key, length); | 1243 checked_key = Add<HBoundsCheck>(key, length); |
1299 HLoadExternalArrayPointer* external_elements = | 1244 HLoadExternalArrayPointer* external_elements = |
1300 Add<HLoadExternalArrayPointer>(elements); | 1245 Add<HLoadExternalArrayPointer>(elements); |
1301 return AddInstruction(BuildExternalArrayElementAccess( | 1246 return AddExternalArrayElementAccess( |
1302 external_elements, checked_key, val, mapcheck, | 1247 external_elements, checked_key, val, |
1303 elements_kind, is_store)); | 1248 mapcheck, elements_kind, is_store); |
1304 } | 1249 } |
1305 } | 1250 } |
1306 ASSERT(fast_smi_only_elements || | 1251 ASSERT(fast_smi_only_elements || |
1307 fast_elements || | 1252 fast_elements || |
1308 IsFastDoubleElementsKind(elements_kind)); | 1253 IsFastDoubleElementsKind(elements_kind)); |
1309 | 1254 |
1310 // In case val is stored into a fast smi array, assure that the value is a smi | 1255 // In case val is stored into a fast smi array, assure that the value is a smi |
1311 // before manipulating the backing store. Otherwise the actual store may | 1256 // before manipulating the backing store. Otherwise the actual store may |
1312 // deopt, leaving the backing store in an invalid state. | 1257 // deopt, leaving the backing store in an invalid state. |
1313 if (is_store && IsFastSmiElementsKind(elements_kind) && | 1258 if (is_store && IsFastSmiElementsKind(elements_kind) && |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1428 elements_location += AllocationMemento::kSize; | 1373 elements_location += AllocationMemento::kSize; |
1429 } | 1374 } |
1430 | 1375 |
1431 HInnerAllocatedObject* elements = | 1376 HInnerAllocatedObject* elements = |
1432 Add<HInnerAllocatedObject>(array, elements_location); | 1377 Add<HInnerAllocatedObject>(array, elements_location); |
1433 AddStore(array, HObjectAccess::ForElementsPointer(), elements); | 1378 AddStore(array, HObjectAccess::ForElementsPointer(), elements); |
1434 return elements; | 1379 return elements; |
1435 } | 1380 } |
1436 | 1381 |
1437 | 1382 |
| 1383 HInstruction* HGraphBuilder::AddExternalArrayElementAccess( |
| 1384 HValue* external_elements, |
| 1385 HValue* checked_key, |
| 1386 HValue* val, |
| 1387 HValue* dependency, |
| 1388 ElementsKind elements_kind, |
| 1389 bool is_store) { |
| 1390 if (is_store) { |
| 1391 ASSERT(val != NULL); |
| 1392 switch (elements_kind) { |
| 1393 case EXTERNAL_PIXEL_ELEMENTS: { |
| 1394 val = Add<HClampToUint8>(val); |
| 1395 break; |
| 1396 } |
| 1397 case EXTERNAL_BYTE_ELEMENTS: |
| 1398 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 1399 case EXTERNAL_SHORT_ELEMENTS: |
| 1400 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 1401 case EXTERNAL_INT_ELEMENTS: |
| 1402 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { |
| 1403 break; |
| 1404 } |
| 1405 case EXTERNAL_FLOAT_ELEMENTS: |
| 1406 case EXTERNAL_DOUBLE_ELEMENTS: |
| 1407 break; |
| 1408 case FAST_SMI_ELEMENTS: |
| 1409 case FAST_ELEMENTS: |
| 1410 case FAST_DOUBLE_ELEMENTS: |
| 1411 case FAST_HOLEY_SMI_ELEMENTS: |
| 1412 case FAST_HOLEY_ELEMENTS: |
| 1413 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 1414 case DICTIONARY_ELEMENTS: |
| 1415 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 1416 UNREACHABLE(); |
| 1417 break; |
| 1418 } |
| 1419 return Add<HStoreKeyed>(external_elements, checked_key, val, elements_kind); |
| 1420 } else { |
| 1421 ASSERT(val == NULL); |
| 1422 HLoadKeyed* load = Add<HLoadKeyed>(external_elements, checked_key, |
| 1423 dependency, elements_kind); |
| 1424 if (FLAG_opt_safe_uint32_operations && |
| 1425 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
| 1426 graph()->RecordUint32Instruction(load); |
| 1427 } |
| 1428 return load; |
| 1429 } |
| 1430 } |
| 1431 |
| 1432 |
1438 HInstruction* HGraphBuilder::AddFastElementAccess( | 1433 HInstruction* HGraphBuilder::AddFastElementAccess( |
1439 HValue* elements, | 1434 HValue* elements, |
1440 HValue* checked_key, | 1435 HValue* checked_key, |
1441 HValue* val, | 1436 HValue* val, |
1442 HValue* load_dependency, | 1437 HValue* load_dependency, |
1443 ElementsKind elements_kind, | 1438 ElementsKind elements_kind, |
1444 bool is_store, | 1439 bool is_store, |
1445 LoadKeyedHoleMode load_mode, | 1440 LoadKeyedHoleMode load_mode, |
1446 KeyedAccessStoreMode store_mode) { | 1441 KeyedAccessStoreMode store_mode) { |
1447 if (is_store) { | 1442 if (is_store) { |
(...skipping 4266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5714 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); | 5709 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); |
5715 } else { | 5710 } else { |
5716 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); | 5711 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); |
5717 } | 5712 } |
5718 } else { | 5713 } else { |
5719 ASSERT(IsExternalArrayElementsKind(elements_kind)); | 5714 ASSERT(IsExternalArrayElementsKind(elements_kind)); |
5720 HInstruction* length = AddLoadFixedArrayLength(elements); | 5715 HInstruction* length = AddLoadFixedArrayLength(elements); |
5721 checked_key = Add<HBoundsCheck>(key, length); | 5716 checked_key = Add<HBoundsCheck>(key, length); |
5722 HLoadExternalArrayPointer* external_elements = | 5717 HLoadExternalArrayPointer* external_elements = |
5723 Add<HLoadExternalArrayPointer>(elements); | 5718 Add<HLoadExternalArrayPointer>(elements); |
5724 access = AddInstruction(BuildExternalArrayElementAccess( | 5719 access = AddExternalArrayElementAccess( |
5725 external_elements, checked_key, val, | 5720 external_elements, checked_key, val, |
5726 mapcompare, elements_kind, is_store)); | 5721 mapcompare, elements_kind, is_store); |
5727 } | 5722 } |
5728 *has_side_effects |= access->HasObservableSideEffects(); | 5723 *has_side_effects |= access->HasObservableSideEffects(); |
5729 // The caller will use has_side_effects and add a correct Simulate. | 5724 // The caller will use has_side_effects and add a correct Simulate. |
5730 access->SetFlag(HValue::kHasNoObservableSideEffects); | 5725 access->SetFlag(HValue::kHasNoObservableSideEffects); |
5731 if (position != RelocInfo::kNoPosition) access->set_position(position); | 5726 if (position != RelocInfo::kNoPosition) access->set_position(position); |
5732 if (!is_store) { | 5727 if (!is_store) { |
5733 Push(access); | 5728 Push(access); |
5734 } | 5729 } |
5735 current_block()->GotoNoSimulate(join); | 5730 current_block()->GotoNoSimulate(join); |
5736 set_current_block(other_map); | 5731 set_current_block(other_map); |
(...skipping 4172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9909 if (ShouldProduceTraceOutput()) { | 9904 if (ShouldProduceTraceOutput()) { |
9910 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9905 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9911 } | 9906 } |
9912 | 9907 |
9913 #ifdef DEBUG | 9908 #ifdef DEBUG |
9914 graph_->Verify(false); // No full verify. | 9909 graph_->Verify(false); // No full verify. |
9915 #endif | 9910 #endif |
9916 } | 9911 } |
9917 | 9912 |
9918 } } // namespace v8::internal | 9913 } } // namespace v8::internal |
OLD | NEW |