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