Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(124)

Side by Side Diff: src/hydrogen.cc

Issue 139973004: A64: Synchronize with r15814. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1035 matching lines...) Expand 10 before | Expand all | Expand 10 after
1046 1046
1047 1047
1048 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, 1048 HValue* HGraphBuilder::BuildCheckMap(HValue* obj,
1049 Handle<Map> map) { 1049 Handle<Map> map) {
1050 HCheckMaps* check = HCheckMaps::New(obj, map, zone()); 1050 HCheckMaps* check = HCheckMaps::New(obj, map, zone());
1051 AddInstruction(check); 1051 AddInstruction(check);
1052 return check; 1052 return check;
1053 } 1053 }
1054 1054
1055 1055
1056 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess(
1057 HValue* external_elements,
1058 HValue* checked_key,
1059 HValue* val,
1060 HValue* dependency,
1061 ElementsKind elements_kind,
1062 bool is_store) {
1063 Zone* zone = this->zone();
1064 if (is_store) {
1065 ASSERT(val != NULL);
1066 switch (elements_kind) {
1067 case EXTERNAL_PIXEL_ELEMENTS: {
1068 val = Add<HClampToUint8>(val);
1069 break;
1070 }
1071 case EXTERNAL_BYTE_ELEMENTS:
1072 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
1073 case EXTERNAL_SHORT_ELEMENTS:
1074 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
1075 case EXTERNAL_INT_ELEMENTS:
1076 case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
1077 break;
1078 }
1079 case EXTERNAL_FLOAT_ELEMENTS:
1080 case EXTERNAL_DOUBLE_ELEMENTS:
1081 break;
1082 case FAST_SMI_ELEMENTS:
1083 case FAST_ELEMENTS:
1084 case FAST_DOUBLE_ELEMENTS:
1085 case FAST_HOLEY_SMI_ELEMENTS:
1086 case FAST_HOLEY_ELEMENTS:
1087 case FAST_HOLEY_DOUBLE_ELEMENTS:
1088 case DICTIONARY_ELEMENTS:
1089 case NON_STRICT_ARGUMENTS_ELEMENTS:
1090 UNREACHABLE();
1091 break;
1092 }
1093 return new(zone) HStoreKeyed(external_elements, checked_key,
1094 val, elements_kind);
1095 } else {
1096 ASSERT(val == NULL);
1097 HLoadKeyed* load =
1098 new(zone) HLoadKeyed(
1099 external_elements, checked_key, dependency, elements_kind);
1100 if (FLAG_opt_safe_uint32_operations &&
1101 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
1102 graph()->RecordUint32Instruction(load);
1103 }
1104 return load;
1105 }
1106 }
1107
1108
1109 HInstruction* HGraphBuilder::BuildFastElementAccess(
1110 HValue* elements,
1111 HValue* checked_key,
1112 HValue* val,
1113 HValue* load_dependency,
1114 ElementsKind elements_kind,
1115 bool is_store,
1116 LoadKeyedHoleMode load_mode,
1117 KeyedAccessStoreMode store_mode) {
1118 Zone* zone = this->zone();
1119 if (is_store) {
1120 ASSERT(val != NULL);
1121 switch (elements_kind) {
1122 case FAST_SMI_ELEMENTS:
1123 case FAST_HOLEY_SMI_ELEMENTS:
1124 case FAST_ELEMENTS:
1125 case FAST_HOLEY_ELEMENTS:
1126 case FAST_DOUBLE_ELEMENTS:
1127 case FAST_HOLEY_DOUBLE_ELEMENTS:
1128 return new(zone) HStoreKeyed(elements, checked_key, val, elements_kind);
1129 default:
1130 UNREACHABLE();
1131 return NULL;
1132 }
1133 }
1134 // It's an element load (!is_store).
1135 return new(zone) HLoadKeyed(elements,
1136 checked_key,
1137 load_dependency,
1138 elements_kind,
1139 load_mode);
1140 }
1141
1142
1143 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, 1056 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
1144 HValue* elements, 1057 HValue* elements,
1145 ElementsKind kind, 1058 ElementsKind kind,
1146 HValue* length, 1059 HValue* length,
1147 HValue* key, 1060 HValue* key,
1148 bool is_js_array) { 1061 bool is_js_array) {
1149 Zone* zone = this->zone(); 1062 Zone* zone = this->zone();
1150 IfBuilder length_checker(this); 1063 IfBuilder length_checker(this);
1151 1064
1152 Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ; 1065 Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1218 cow_checker.Else(); 1131 cow_checker.Else();
1219 1132
1220 environment()->Push(elements); 1133 environment()->Push(elements);
1221 1134
1222 cow_checker.End(); 1135 cow_checker.End();
1223 1136
1224 return environment()->Pop(); 1137 return environment()->Pop();
1225 } 1138 }
1226 1139
1227 1140
1141 void HGraphBuilder::BuildTransitionElementsKind(HValue* object,
1142 HValue* map,
1143 ElementsKind from_kind,
1144 ElementsKind to_kind,
1145 bool is_jsarray) {
1146 ASSERT(!IsFastHoleyElementsKind(from_kind) ||
1147 IsFastHoleyElementsKind(to_kind));
1148
1149 if (AllocationSite::GetMode(from_kind, to_kind) == TRACK_ALLOCATION_SITE) {
1150 Add<HTrapAllocationMemento>(object);
1151 }
1152
1153 if (!IsSimpleMapChangeTransition(from_kind, to_kind)) {
1154 HInstruction* elements = AddLoadElements(object);
1155
1156 HInstruction* empty_fixed_array = Add<HConstant>(
1157 isolate()->factory()->empty_fixed_array(), Representation::Tagged());
1158
1159 IfBuilder if_builder(this);
1160
1161 if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array);
1162
1163 if_builder.Then();
1164
1165 HInstruction* elements_length = AddLoadFixedArrayLength(elements);
1166
1167 HInstruction* array_length = is_jsarray
1168 ? AddLoad(object, HObjectAccess::ForArrayLength(),
1169 NULL, Representation::Smi())
1170 : elements_length;
1171 array_length->set_type(HType::Smi());
1172
1173 BuildGrowElementsCapacity(object, elements, from_kind, to_kind,
1174 array_length, elements_length);
1175
1176 if_builder.End();
1177 }
1178
1179 AddStore(object, HObjectAccess::ForMap(), map);
1180 }
1181
1182
1228 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( 1183 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
1229 HValue* object, 1184 HValue* object,
1230 HValue* key, 1185 HValue* key,
1231 HValue* val, 1186 HValue* val,
1232 HCheckMaps* mapcheck, 1187 HCheckMaps* mapcheck,
1233 bool is_js_array, 1188 bool is_js_array,
1234 ElementsKind elements_kind, 1189 ElementsKind elements_kind,
1235 bool is_store, 1190 bool is_store,
1236 LoadKeyedHoleMode load_mode, 1191 LoadKeyedHoleMode load_mode,
1237 KeyedAccessStoreMode store_mode) { 1192 KeyedAccessStoreMode store_mode) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 NoObservableSideEffectsScope no_effects(this); 1228 NoObservableSideEffectsScope no_effects(this);
1274 HLoadExternalArrayPointer* external_elements = 1229 HLoadExternalArrayPointer* external_elements =
1275 Add<HLoadExternalArrayPointer>(elements); 1230 Add<HLoadExternalArrayPointer>(elements);
1276 IfBuilder length_checker(this); 1231 IfBuilder length_checker(this);
1277 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); 1232 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT);
1278 length_checker.Then(); 1233 length_checker.Then();
1279 IfBuilder negative_checker(this); 1234 IfBuilder negative_checker(this);
1280 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( 1235 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>(
1281 key, graph()->GetConstant0(), Token::GTE); 1236 key, graph()->GetConstant0(), Token::GTE);
1282 negative_checker.Then(); 1237 negative_checker.Then();
1283 HInstruction* result = BuildExternalArrayElementAccess( 1238 HInstruction* result = AddExternalArrayElementAccess(
1284 external_elements, key, val, bounds_check, 1239 external_elements, key, val, bounds_check, elements_kind, is_store);
1285 elements_kind, is_store);
1286 AddInstruction(result);
1287 negative_checker.ElseDeopt(); 1240 negative_checker.ElseDeopt();
1288 length_checker.End(); 1241 length_checker.End();
1289 return result; 1242 return result;
1290 } else { 1243 } else {
1291 ASSERT(store_mode == STANDARD_STORE); 1244 ASSERT(store_mode == STANDARD_STORE);
1292 checked_key = Add<HBoundsCheck>(key, length); 1245 checked_key = Add<HBoundsCheck>(key, length);
1293 HLoadExternalArrayPointer* external_elements = 1246 HLoadExternalArrayPointer* external_elements =
1294 Add<HLoadExternalArrayPointer>(elements); 1247 Add<HLoadExternalArrayPointer>(elements);
1295 return AddInstruction(BuildExternalArrayElementAccess( 1248 return AddExternalArrayElementAccess(
1296 external_elements, checked_key, val, mapcheck, 1249 external_elements, checked_key, val,
1297 elements_kind, is_store)); 1250 mapcheck, elements_kind, is_store);
1298 } 1251 }
1299 } 1252 }
1300 ASSERT(fast_smi_only_elements || 1253 ASSERT(fast_smi_only_elements ||
1301 fast_elements || 1254 fast_elements ||
1302 IsFastDoubleElementsKind(elements_kind)); 1255 IsFastDoubleElementsKind(elements_kind));
1303 1256
1304 // In case val is stored into a fast smi array, assure that the value is a smi 1257 // In case val is stored into a fast smi array, assure that the value is a smi
1305 // before manipulating the backing store. Otherwise the actual store may 1258 // before manipulating the backing store. Otherwise the actual store may
1306 // deopt, leaving the backing store in an invalid state. 1259 // deopt, leaving the backing store in an invalid state.
1307 if (is_store && IsFastSmiElementsKind(elements_kind) && 1260 if (is_store && IsFastSmiElementsKind(elements_kind) &&
(...skipping 16 matching lines...) Expand all
1324 elements = BuildCopyElementsOnWrite(object, elements, elements_kind, 1277 elements = BuildCopyElementsOnWrite(object, elements, elements_kind,
1325 length); 1278 length);
1326 } else { 1279 } else {
1327 HCheckMaps* check_cow_map = HCheckMaps::New( 1280 HCheckMaps* check_cow_map = HCheckMaps::New(
1328 elements, isolate()->factory()->fixed_array_map(), zone); 1281 elements, isolate()->factory()->fixed_array_map(), zone);
1329 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); 1282 check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
1330 AddInstruction(check_cow_map); 1283 AddInstruction(check_cow_map);
1331 } 1284 }
1332 } 1285 }
1333 } 1286 }
1334 return AddInstruction( 1287 return AddFastElementAccess(elements, checked_key, val, mapcheck,
1335 BuildFastElementAccess(elements, checked_key, val, mapcheck, 1288 elements_kind, is_store, load_mode, store_mode);
1336 elements_kind, is_store, load_mode, store_mode));
1337 } 1289 }
1338 1290
1339 1291
1340 HValue* HGraphBuilder::BuildAllocateElements(HValue* context, 1292 HValue* HGraphBuilder::BuildAllocateElements(HValue* context,
1341 ElementsKind kind, 1293 ElementsKind kind,
1342 HValue* capacity) { 1294 HValue* capacity) {
1343 Zone* zone = this->zone(); 1295 Zone* zone = this->zone();
1344 1296
1345 int elements_size = IsFastDoubleElementsKind(kind) 1297 int elements_size = IsFastDoubleElementsKind(kind)
1346 ? kDoubleSize : kPointerSize; 1298 ? kDoubleSize : kPointerSize;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1406 AddStore(array, HObjectAccess::ForMap(), array_map); 1358 AddStore(array, HObjectAccess::ForMap(), array_map);
1407 1359
1408 HConstant* empty_fixed_array = 1360 HConstant* empty_fixed_array =
1409 Add<HConstant>(isolate()->factory()->empty_fixed_array()); 1361 Add<HConstant>(isolate()->factory()->empty_fixed_array());
1410 1362
1411 HObjectAccess access = HObjectAccess::ForPropertiesPointer(); 1363 HObjectAccess access = HObjectAccess::ForPropertiesPointer();
1412 AddStore(array, access, empty_fixed_array); 1364 AddStore(array, access, empty_fixed_array);
1413 AddStore(array, HObjectAccess::ForArrayLength(), length_field); 1365 AddStore(array, HObjectAccess::ForArrayLength(), length_field);
1414 1366
1415 if (mode == TRACK_ALLOCATION_SITE) { 1367 if (mode == TRACK_ALLOCATION_SITE) {
1416 BuildCreateAllocationSiteInfo(array, 1368 BuildCreateAllocationMemento(array,
1417 JSArray::kSize, 1369 JSArray::kSize,
1418 allocation_site_payload); 1370 allocation_site_payload);
1419 } 1371 }
1420 1372
1421 int elements_location = JSArray::kSize; 1373 int elements_location = JSArray::kSize;
1422 if (mode == TRACK_ALLOCATION_SITE) { 1374 if (mode == TRACK_ALLOCATION_SITE) {
1423 elements_location += AllocationSiteInfo::kSize; 1375 elements_location += AllocationMemento::kSize;
1424 } 1376 }
1425 1377
1426 HInnerAllocatedObject* elements = 1378 HInnerAllocatedObject* elements =
1427 Add<HInnerAllocatedObject>(array, elements_location); 1379 Add<HInnerAllocatedObject>(array, elements_location);
1428 AddStore(array, HObjectAccess::ForElementsPointer(), elements); 1380 AddStore(array, HObjectAccess::ForElementsPointer(), elements);
1429 return elements; 1381 return elements;
1430 } 1382 }
1431 1383
1432 1384
1385 HInstruction* HGraphBuilder::AddExternalArrayElementAccess(
1386 HValue* external_elements,
1387 HValue* checked_key,
1388 HValue* val,
1389 HValue* dependency,
1390 ElementsKind elements_kind,
1391 bool is_store) {
1392 if (is_store) {
1393 ASSERT(val != NULL);
1394 switch (elements_kind) {
1395 case EXTERNAL_PIXEL_ELEMENTS: {
1396 val = Add<HClampToUint8>(val);
1397 break;
1398 }
1399 case EXTERNAL_BYTE_ELEMENTS:
1400 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
1401 case EXTERNAL_SHORT_ELEMENTS:
1402 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
1403 case EXTERNAL_INT_ELEMENTS:
1404 case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
1405 break;
1406 }
1407 case EXTERNAL_FLOAT_ELEMENTS:
1408 case EXTERNAL_DOUBLE_ELEMENTS:
1409 break;
1410 case FAST_SMI_ELEMENTS:
1411 case FAST_ELEMENTS:
1412 case FAST_DOUBLE_ELEMENTS:
1413 case FAST_HOLEY_SMI_ELEMENTS:
1414 case FAST_HOLEY_ELEMENTS:
1415 case FAST_HOLEY_DOUBLE_ELEMENTS:
1416 case DICTIONARY_ELEMENTS:
1417 case NON_STRICT_ARGUMENTS_ELEMENTS:
1418 UNREACHABLE();
1419 break;
1420 }
1421 return Add<HStoreKeyed>(external_elements, checked_key, val, elements_kind);
1422 } else {
1423 ASSERT(val == NULL);
1424 HLoadKeyed* load = Add<HLoadKeyed>(external_elements, checked_key,
1425 dependency, elements_kind);
1426 if (FLAG_opt_safe_uint32_operations &&
1427 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
1428 graph()->RecordUint32Instruction(load);
1429 }
1430 return load;
1431 }
1432 }
1433
1434
1435 HInstruction* HGraphBuilder::AddFastElementAccess(
1436 HValue* elements,
1437 HValue* checked_key,
1438 HValue* val,
1439 HValue* load_dependency,
1440 ElementsKind elements_kind,
1441 bool is_store,
1442 LoadKeyedHoleMode load_mode,
1443 KeyedAccessStoreMode store_mode) {
1444 if (is_store) {
1445 ASSERT(val != NULL);
1446 switch (elements_kind) {
1447 case FAST_SMI_ELEMENTS:
1448 case FAST_HOLEY_SMI_ELEMENTS:
1449 case FAST_ELEMENTS:
1450 case FAST_HOLEY_ELEMENTS:
1451 case FAST_DOUBLE_ELEMENTS:
1452 case FAST_HOLEY_DOUBLE_ELEMENTS:
1453 return Add<HStoreKeyed>(elements, checked_key, val, elements_kind);
1454 default:
1455 UNREACHABLE();
1456 return NULL;
1457 }
1458 }
1459 // It's an element load (!is_store).
1460 return Add<HLoadKeyed>(
1461 elements, checked_key, load_dependency, elements_kind, load_mode);
1462 }
1463
1464
1433 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object, 1465 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object,
1434 HValue* typecheck) { 1466 HValue* typecheck) {
1435 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck); 1467 return AddLoad(object, HObjectAccess::ForElementsPointer(), typecheck);
1436 } 1468 }
1437 1469
1438 1470
1439 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) { 1471 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) {
1440 HLoadNamedField* instr = AddLoad(object, HObjectAccess::ForFixedArrayLength(), 1472 HLoadNamedField* instr = AddLoad(object, HObjectAccess::ForFixedArrayLength(),
1441 NULL, Representation::Smi()); 1473 NULL, Representation::Smi());
1442 instr->set_type(HType::Smi()); 1474 instr->set_type(HType::Smi());
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1607 HValue* boilerplate, 1639 HValue* boilerplate,
1608 HValue* allocation_site, 1640 HValue* allocation_site,
1609 AllocationSiteMode mode, 1641 AllocationSiteMode mode,
1610 ElementsKind kind, 1642 ElementsKind kind,
1611 int length) { 1643 int length) {
1612 NoObservableSideEffectsScope no_effects(this); 1644 NoObservableSideEffectsScope no_effects(this);
1613 1645
1614 // All sizes here are multiples of kPointerSize. 1646 // All sizes here are multiples of kPointerSize.
1615 int size = JSArray::kSize; 1647 int size = JSArray::kSize;
1616 if (mode == TRACK_ALLOCATION_SITE) { 1648 if (mode == TRACK_ALLOCATION_SITE) {
1617 size += AllocationSiteInfo::kSize; 1649 size += AllocationMemento::kSize;
1618 } 1650 }
1619 int elems_offset = size; 1651 int elems_offset = size;
1620 if (length > 0) { 1652 if (length > 0) {
1621 size += IsFastDoubleElementsKind(kind) 1653 size += IsFastDoubleElementsKind(kind)
1622 ? FixedDoubleArray::SizeFor(length) 1654 ? FixedDoubleArray::SizeFor(length)
1623 : FixedArray::SizeFor(length); 1655 : FixedArray::SizeFor(length);
1624 } 1656 }
1625 1657
1626 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind); 1658 HAllocate::Flags allocate_flags = HAllocate::DefaultFlags(kind);
1627 // Allocate both the JS array and the elements array in one big 1659 // Allocate both the JS array and the elements array in one big
1628 // allocation. This avoids multiple limit checks. 1660 // allocation. This avoids multiple limit checks.
1629 HValue* size_in_bytes = Add<HConstant>(size); 1661 HValue* size_in_bytes = Add<HConstant>(size);
1630 HInstruction* object = Add<HAllocate>(context, 1662 HInstruction* object = Add<HAllocate>(context,
1631 size_in_bytes, 1663 size_in_bytes,
1632 HType::JSObject(), 1664 HType::JSObject(),
1633 allocate_flags); 1665 allocate_flags);
1634 1666
1635 // Copy the JS array part. 1667 // Copy the JS array part.
1636 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { 1668 for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
1637 if ((i != JSArray::kElementsOffset) || (length == 0)) { 1669 if ((i != JSArray::kElementsOffset) || (length == 0)) {
1638 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i); 1670 HObjectAccess access = HObjectAccess::ForJSArrayOffset(i);
1639 AddStore(object, access, AddLoad(boilerplate, access)); 1671 AddStore(object, access, AddLoad(boilerplate, access));
1640 } 1672 }
1641 } 1673 }
1642 1674
1643 // Create an allocation site info if requested. 1675 // Create an allocation site info if requested.
1644 if (mode == TRACK_ALLOCATION_SITE) { 1676 if (mode == TRACK_ALLOCATION_SITE) {
1645 BuildCreateAllocationSiteInfo(object, JSArray::kSize, allocation_site); 1677 BuildCreateAllocationMemento(object, JSArray::kSize, allocation_site);
1646 } 1678 }
1647 1679
1648 if (length > 0) { 1680 if (length > 0) {
1649 // Get hold of the elements array of the boilerplate and setup the 1681 // Get hold of the elements array of the boilerplate and setup the
1650 // elements pointer in the resulting object. 1682 // elements pointer in the resulting object.
1651 HValue* boilerplate_elements = AddLoadElements(boilerplate); 1683 HValue* boilerplate_elements = AddLoadElements(boilerplate);
1652 HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset); 1684 HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset);
1653 AddStore(object, HObjectAccess::ForElementsPointer(), object_elements); 1685 AddStore(object, HObjectAccess::ForElementsPointer(), object_elements);
1654 1686
1655 // Copy the elements array header. 1687 // Copy the elements array header.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1740 BuildCheckMap(value, type->Classes().Current()); 1772 BuildCheckMap(value, type->Classes().Current());
1741 } else { 1773 } else {
1742 if_nil.Deopt(); 1774 if_nil.Deopt();
1743 } 1775 }
1744 } 1776 }
1745 1777
1746 if_nil.CaptureContinuation(continuation); 1778 if_nil.CaptureContinuation(continuation);
1747 } 1779 }
1748 1780
1749 1781
1750 HValue* HGraphBuilder::BuildCreateAllocationSiteInfo(HValue* previous_object, 1782 HValue* HGraphBuilder::BuildCreateAllocationMemento(HValue* previous_object,
1751 int previous_object_size, 1783 int previous_object_size,
1752 HValue* alloc_site) { 1784 HValue* alloc_site) {
1753 ASSERT(alloc_site != NULL); 1785 ASSERT(alloc_site != NULL);
1754 HInnerAllocatedObject* alloc_site_info = Add<HInnerAllocatedObject>( 1786 HInnerAllocatedObject* alloc_memento = Add<HInnerAllocatedObject>(
1755 previous_object, previous_object_size); 1787 previous_object, previous_object_size);
1756 Handle<Map> alloc_site_info_map( 1788 Handle<Map> alloc_memento_map(
1757 isolate()->heap()->allocation_site_info_map()); 1789 isolate()->heap()->allocation_memento_map());
1758 AddStoreMapConstant(alloc_site_info, alloc_site_info_map); 1790 AddStoreMapConstant(alloc_memento, alloc_memento_map);
1759 HObjectAccess access = HObjectAccess::ForAllocationSiteInfoSite(); 1791 HObjectAccess access = HObjectAccess::ForAllocationMementoSite();
1760 AddStore(alloc_site_info, access, alloc_site); 1792 AddStore(alloc_memento, access, alloc_site);
1761 return alloc_site_info; 1793 return alloc_memento;
1762 } 1794 }
1763 1795
1764 1796
1765 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* context) { 1797 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* context) {
1766 // Get the global context, then the native context 1798 // Get the global context, then the native context
1767 HInstruction* global_object = Add<HGlobalObject>(context); 1799 HInstruction* global_object = Add<HGlobalObject>(context);
1768 HObjectAccess access = HObjectAccess::ForJSObjectOffset( 1800 HObjectAccess access = HObjectAccess::ForJSObjectOffset(
1769 GlobalObject::kNativeContextOffset); 1801 GlobalObject::kNativeContextOffset);
1770 return AddLoad(global_object, access); 1802 return AddLoad(global_object, access);
1771 } 1803 }
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1842 } 1874 }
1843 1875
1844 1876
1845 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( 1877 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize(
1846 HValue* length_node) { 1878 HValue* length_node) {
1847 HValue* context = builder()->environment()->LookupContext(); 1879 HValue* context = builder()->environment()->LookupContext();
1848 ASSERT(length_node != NULL); 1880 ASSERT(length_node != NULL);
1849 1881
1850 int base_size = JSArray::kSize; 1882 int base_size = JSArray::kSize;
1851 if (mode_ == TRACK_ALLOCATION_SITE) { 1883 if (mode_ == TRACK_ALLOCATION_SITE) {
1852 base_size += AllocationSiteInfo::kSize; 1884 base_size += AllocationMemento::kSize;
1853 } 1885 }
1854 1886
1855 if (IsFastDoubleElementsKind(kind_)) { 1887 if (IsFastDoubleElementsKind(kind_)) {
1856 base_size += FixedDoubleArray::kHeaderSize; 1888 base_size += FixedDoubleArray::kHeaderSize;
1857 } else { 1889 } else {
1858 base_size += FixedArray::kHeaderSize; 1890 base_size += FixedArray::kHeaderSize;
1859 } 1891 }
1860 1892
1861 HInstruction* elements_size_value = 1893 HInstruction* elements_size_value =
1862 builder()->Add<HConstant>(elements_size()); 1894 builder()->Add<HConstant>(elements_size());
1863 HInstruction* mul = HMul::New(zone(), context, length_node, 1895 HInstruction* mul = HMul::New(zone(), context, length_node,
1864 elements_size_value); 1896 elements_size_value);
1865 mul->ClearFlag(HValue::kCanOverflow); 1897 mul->ClearFlag(HValue::kCanOverflow);
1866 builder()->AddInstruction(mul); 1898 builder()->AddInstruction(mul);
1867 1899
1868 HInstruction* base = builder()->Add<HConstant>(base_size); 1900 HInstruction* base = builder()->Add<HConstant>(base_size);
1869 HInstruction* total_size = HAdd::New(zone(), context, base, mul); 1901 HInstruction* total_size = HAdd::New(zone(), context, base, mul);
1870 total_size->ClearFlag(HValue::kCanOverflow); 1902 total_size->ClearFlag(HValue::kCanOverflow);
1871 builder()->AddInstruction(total_size); 1903 builder()->AddInstruction(total_size);
1872 return total_size; 1904 return total_size;
1873 } 1905 }
1874 1906
1875 1907
1876 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() { 1908 HValue* HGraphBuilder::JSArrayBuilder::EstablishEmptyArrayAllocationSize() {
1877 int base_size = JSArray::kSize; 1909 int base_size = JSArray::kSize;
1878 if (mode_ == TRACK_ALLOCATION_SITE) { 1910 if (mode_ == TRACK_ALLOCATION_SITE) {
1879 base_size += AllocationSiteInfo::kSize; 1911 base_size += AllocationMemento::kSize;
1880 } 1912 }
1881 1913
1882 base_size += IsFastDoubleElementsKind(kind_) 1914 base_size += IsFastDoubleElementsKind(kind_)
1883 ? FixedDoubleArray::SizeFor(initial_capacity()) 1915 ? FixedDoubleArray::SizeFor(initial_capacity())
1884 : FixedArray::SizeFor(initial_capacity()); 1916 : FixedArray::SizeFor(initial_capacity());
1885 1917
1886 return builder()->Add<HConstant>(base_size); 1918 return builder()->Add<HConstant>(base_size);
1887 } 1919 }
1888 1920
1889 1921
(...skipping 2491 matching lines...) Expand 10 before | Expand all | Expand 10 after
4381 // Check whether to use fast or slow deep-copying for boilerplate. 4413 // Check whether to use fast or slow deep-copying for boilerplate.
4382 int data_size = 0; 4414 int data_size = 0;
4383 int pointer_size = 0; 4415 int pointer_size = 0;
4384 int max_properties = kMaxFastLiteralProperties; 4416 int max_properties = kMaxFastLiteralProperties;
4385 if (IsFastLiteral(original_boilerplate_object, 4417 if (IsFastLiteral(original_boilerplate_object,
4386 kMaxFastLiteralDepth, 4418 kMaxFastLiteralDepth,
4387 &max_properties, 4419 &max_properties,
4388 &data_size, 4420 &data_size,
4389 &pointer_size)) { 4421 &pointer_size)) {
4390 if (mode == TRACK_ALLOCATION_SITE) { 4422 if (mode == TRACK_ALLOCATION_SITE) {
4391 pointer_size += AllocationSiteInfo::kSize; 4423 pointer_size += AllocationMemento::kSize;
4392 } 4424 }
4393 4425
4394 Handle<JSObject> boilerplate_object = DeepCopy(original_boilerplate_object); 4426 Handle<JSObject> boilerplate_object = DeepCopy(original_boilerplate_object);
4395 literal = BuildFastLiteral(context, 4427 literal = BuildFastLiteral(context,
4396 boilerplate_object, 4428 boilerplate_object,
4397 original_boilerplate_object, 4429 original_boilerplate_object,
4398 site, 4430 site,
4399 data_size, 4431 data_size,
4400 pointer_size, 4432 pointer_size,
4401 mode); 4433 mode);
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
4782 if (count != types->length()) return false; 4814 if (count != types->length()) return false;
4783 4815
4784 // Everything matched; can use monomorphic store. 4816 // Everything matched; can use monomorphic store.
4785 BuildCheckHeapObject(object); 4817 BuildCheckHeapObject(object);
4786 AddInstruction(HCheckMaps::New(object, types, zone())); 4818 AddInstruction(HCheckMaps::New(object, types, zone()));
4787 HInstruction* store; 4819 HInstruction* store;
4788 CHECK_ALIVE_OR_RETURN( 4820 CHECK_ALIVE_OR_RETURN(
4789 store = BuildStoreNamedField( 4821 store = BuildStoreNamedField(
4790 object, name, store_value, types->at(count - 1), &lookup), 4822 object, name, store_value, types->at(count - 1), &lookup),
4791 true); 4823 true);
4792 if (result_value != NULL) Push(result_value); 4824 if (!ast_context()->IsEffect()) Push(result_value);
4793 Push(store_value);
4794 store->set_position(position); 4825 store->set_position(position);
4795 AddInstruction(store); 4826 AddInstruction(store);
4796 AddSimulate(assignment_id); 4827 AddSimulate(assignment_id);
4797 if (result_value != NULL) Drop(1); 4828 if (!ast_context()->IsEffect()) Drop(1);
4798 ast_context()->ReturnValue(Pop()); 4829 ast_context()->ReturnValue(result_value);
4799 return true; 4830 return true;
4800 } 4831 }
4801 4832
4802 4833
4803 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( 4834 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
4804 BailoutId id,
4805 int position, 4835 int position,
4806 BailoutId assignment_id, 4836 BailoutId assignment_id,
4807 HValue* object, 4837 HValue* object,
4808 HValue* store_value, 4838 HValue* store_value,
4809 HValue* result_value, 4839 HValue* result_value,
4810 SmallMapList* types, 4840 SmallMapList* types,
4811 Handle<String> name) { 4841 Handle<String> name) {
4812 if (TryStorePolymorphicAsMonomorphic( 4842 if (TryStorePolymorphicAsMonomorphic(
4813 position, assignment_id, object, 4843 position, assignment_id, object,
4814 store_value, result_value, types, name)) { 4844 store_value, result_value, types, name)) {
(...skipping 20 matching lines...) Expand all
4835 new(zone()) HCompareMap(object, map, if_true, if_false); 4865 new(zone()) HCompareMap(object, map, if_true, if_false);
4836 current_block()->Finish(compare); 4866 current_block()->Finish(compare);
4837 4867
4838 set_current_block(if_true); 4868 set_current_block(if_true);
4839 HInstruction* instr; 4869 HInstruction* instr;
4840 CHECK_ALIVE(instr = BuildStoreNamedField( 4870 CHECK_ALIVE(instr = BuildStoreNamedField(
4841 object, name, store_value, map, &lookup)); 4871 object, name, store_value, map, &lookup));
4842 instr->set_position(position); 4872 instr->set_position(position);
4843 // Goto will add the HSimulate for the store. 4873 // Goto will add the HSimulate for the store.
4844 AddInstruction(instr); 4874 AddInstruction(instr);
4845 if (!ast_context()->IsEffect()) { 4875 if (!ast_context()->IsEffect()) Push(result_value);
4846 if (result_value != NULL) Push(result_value);
4847 Push(store_value);
4848 }
4849 current_block()->Goto(join); 4876 current_block()->Goto(join);
4850 4877
4851 set_current_block(if_false); 4878 set_current_block(if_false);
4852 } 4879 }
4853 } 4880 }
4854 4881
4855 // Finish up. Unconditionally deoptimize if we've handled all the maps we 4882 // Finish up. Unconditionally deoptimize if we've handled all the maps we
4856 // know about and do not want to handle ones we've never seen. Otherwise 4883 // know about and do not want to handle ones we've never seen. Otherwise
4857 // use a generic IC. 4884 // use a generic IC.
4858 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 4885 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
4859 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); 4886 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
4860 } else { 4887 } else {
4861 HInstruction* instr = BuildStoreNamedGeneric(object, name, store_value); 4888 HInstruction* instr = BuildStoreNamedGeneric(object, name, store_value);
4862 instr->set_position(position); 4889 instr->set_position(position);
4863 AddInstruction(instr); 4890 AddInstruction(instr);
4864 4891
4865 if (join != NULL) { 4892 if (join != NULL) {
4866 if (!ast_context()->IsEffect()) { 4893 if (!ast_context()->IsEffect()) {
4867 if (result_value != NULL) Push(result_value); 4894 Push(result_value);
4868 Push(store_value);
4869 } 4895 }
4870 current_block()->Goto(join); 4896 current_block()->Goto(join);
4871 } else { 4897 } else {
4872 // The HSimulate for the store should not see the stored value in 4898 // The HSimulate for the store should not see the stored value in
4873 // effect contexts (it is not materialized at expr->id() in the 4899 // effect contexts (it is not materialized at expr->id() in the
4874 // unoptimized code). 4900 // unoptimized code).
4875 if (instr->HasObservableSideEffects()) { 4901 if (instr->HasObservableSideEffects()) {
4876 if (ast_context()->IsEffect()) { 4902 if (ast_context()->IsEffect()) {
4877 AddSimulate(id, REMOVABLE_SIMULATE); 4903 AddSimulate(assignment_id, REMOVABLE_SIMULATE);
4878 } else { 4904 } else {
4879 if (result_value != NULL) Push(result_value); 4905 Push(result_value);
4880 Push(store_value); 4906 AddSimulate(assignment_id, REMOVABLE_SIMULATE);
4881 AddSimulate(id, REMOVABLE_SIMULATE); 4907 Drop(1);
4882 Drop(result_value != NULL ? 2 : 1);
4883 } 4908 }
4884 } 4909 }
4885 return ast_context()->ReturnValue( 4910 return ast_context()->ReturnValue(result_value);
4886 result_value != NULL ? result_value : store_value);
4887 } 4911 }
4888 } 4912 }
4889 4913
4890 ASSERT(join != NULL); 4914 ASSERT(join != NULL);
4891 join->SetJoinId(id); 4915 join->SetJoinId(assignment_id);
4892 set_current_block(join); 4916 set_current_block(join);
4893 if (!ast_context()->IsEffect()) { 4917 if (!ast_context()->IsEffect()) {
4894 if (result_value != NULL) Drop(1);
4895 ast_context()->ReturnValue(Pop()); 4918 ast_context()->ReturnValue(Pop());
4896 } 4919 }
4897 } 4920 }
4898 4921
4899 4922
4900 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) { 4923 void HOptimizedGraphBuilder::HandlePropertyAssignment(Assignment* expr) {
4901 Property* prop = expr->target()->AsProperty(); 4924 Property* prop = expr->target()->AsProperty();
4902 ASSERT(prop != NULL); 4925 ASSERT(prop != NULL);
4903 CHECK_ALIVE(VisitForValue(prop->obj())); 4926 CHECK_ALIVE(VisitForValue(prop->obj()));
4904 4927
4905 if (prop->key()->IsPropertyName()) { 4928 if (prop->key()->IsPropertyName()) {
4906 // Named store. 4929 // Named store.
4907 CHECK_ALIVE(VisitForValue(expr->value())); 4930 CHECK_ALIVE(VisitForValue(expr->value()));
4908 HValue* value = environment()->ExpressionStackAt(0); 4931 HValue* value = environment()->ExpressionStackAt(0);
4909 HValue* object = environment()->ExpressionStackAt(1); 4932 HValue* object = environment()->ExpressionStackAt(1);
4910 4933
4911 if (expr->IsUninitialized()) AddSoftDeoptimize(); 4934 if (expr->IsUninitialized()) AddSoftDeoptimize();
4912 return BuildStoreNamed(expr, expr->id(), expr->position(), 4935 return BuildStoreNamed(expr, expr->id(), expr->position(),
4913 expr->AssignmentId(), prop, object, value); 4936 expr->AssignmentId(), prop, object, value, value);
4914 } else { 4937 } else {
4915 // Keyed store. 4938 // Keyed store.
4916 CHECK_ALIVE(VisitForValue(prop->key())); 4939 CHECK_ALIVE(VisitForValue(prop->key()));
4917 CHECK_ALIVE(VisitForValue(expr->value())); 4940 CHECK_ALIVE(VisitForValue(expr->value()));
4918 HValue* value = environment()->ExpressionStackAt(0); 4941 HValue* value = environment()->ExpressionStackAt(0);
4919 HValue* key = environment()->ExpressionStackAt(1); 4942 HValue* key = environment()->ExpressionStackAt(1);
4920 HValue* object = environment()->ExpressionStackAt(2); 4943 HValue* object = environment()->ExpressionStackAt(2);
4921 bool has_side_effects = false; 4944 bool has_side_effects = false;
4922 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(), 4945 HandleKeyedElementAccess(object, key, value, expr, expr->AssignmentId(),
4923 expr->position(), 4946 expr->position(),
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
4996 map = types->first(); 5019 map = types->first();
4997 if (map->is_dictionary_map()) monomorphic = false; 5020 if (map->is_dictionary_map()) monomorphic = false;
4998 } 5021 }
4999 if (monomorphic) { 5022 if (monomorphic) {
5000 Handle<JSFunction> setter; 5023 Handle<JSFunction> setter;
5001 Handle<JSObject> holder; 5024 Handle<JSObject> holder;
5002 if (LookupSetter(map, name, &setter, &holder)) { 5025 if (LookupSetter(map, name, &setter, &holder)) {
5003 AddCheckConstantFunction(holder, object, map); 5026 AddCheckConstantFunction(holder, object, map);
5004 // Don't try to inline if the result_value is different from the 5027 // Don't try to inline if the result_value is different from the
5005 // store_value. That case isn't handled yet by the inlining. 5028 // store_value. That case isn't handled yet by the inlining.
5006 if (result_value == NULL && 5029 if (result_value == store_value &&
5007 FLAG_inline_accessors && 5030 FLAG_inline_accessors &&
5008 TryInlineSetter(setter, id, assignment_id, store_value)) { 5031 TryInlineSetter(setter, id, assignment_id, store_value)) {
5009 return; 5032 return;
5010 } 5033 }
5011 Drop(2); 5034 Drop(2);
5012 Add<HPushArgument>(object); 5035 Add<HPushArgument>(object);
5013 Add<HPushArgument>(store_value); 5036 Add<HPushArgument>(store_value);
5014 instr = new(zone()) HCallConstantFunction(setter, 2); 5037 instr = new(zone()) HCallConstantFunction(setter, 2);
5015 } else { 5038 } else {
5016 Drop(2); 5039 Drop(2);
5017 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, 5040 CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object,
5018 name, 5041 name,
5019 store_value, 5042 store_value,
5020 map)); 5043 map));
5021 } 5044 }
5022 } else if (types != NULL && types->length() > 1) { 5045 } else if (types != NULL && types->length() > 1) {
5023 Drop(2); 5046 Drop(2);
5024 return HandlePolymorphicStoreNamedField( 5047 return HandlePolymorphicStoreNamedField(
5025 id, position, assignment_id, object, 5048 position, id, object,
5026 store_value, result_value, types, name); 5049 store_value, result_value, types, name);
5027 } else { 5050 } else {
5028 Drop(2); 5051 Drop(2);
5029 instr = BuildStoreNamedGeneric(object, name, store_value); 5052 instr = BuildStoreNamedGeneric(object, name, store_value);
5030 } 5053 }
5031 5054
5032 if (result_value != NULL) Push(result_value); 5055 if (!ast_context()->IsEffect()) Push(result_value);
5033 Push(store_value);
5034 instr->set_position(position); 5056 instr->set_position(position);
5035 AddInstruction(instr); 5057 AddInstruction(instr);
5036 if (instr->HasObservableSideEffects()) { 5058 if (instr->HasObservableSideEffects()) {
5037 AddSimulate(assignment_id, REMOVABLE_SIMULATE); 5059 AddSimulate(id, REMOVABLE_SIMULATE);
5038 } 5060 }
5039 if (result_value != NULL) Drop(1); 5061 if (!ast_context()->IsEffect()) Drop(1);
5040 return ast_context()->ReturnValue(Pop()); 5062 return ast_context()->ReturnValue(result_value);
5041 } 5063 }
5042 5064
5043 5065
5044 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 5066 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
5045 Expression* target = expr->target(); 5067 Expression* target = expr->target();
5046 VariableProxy* proxy = target->AsVariableProxy(); 5068 VariableProxy* proxy = target->AsVariableProxy();
5047 Property* prop = target->AsProperty(); 5069 Property* prop = target->AsProperty();
5048 ASSERT(proxy == NULL || prop == NULL); 5070 ASSERT(proxy == NULL || prop == NULL);
5049 5071
5050 // We have a second position recorded in the FullCodeGenerator to have 5072 // We have a second position recorded in the FullCodeGenerator to have
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
5160 HValue* right = Pop(); 5182 HValue* right = Pop();
5161 HValue* left = Pop(); 5183 HValue* left = Pop();
5162 5184
5163 HInstruction* instr = BuildBinaryOperation(operation, left, right); 5185 HInstruction* instr = BuildBinaryOperation(operation, left, right);
5164 PushAndAdd(instr); 5186 PushAndAdd(instr);
5165 if (instr->HasObservableSideEffects()) { 5187 if (instr->HasObservableSideEffects()) {
5166 AddSimulate(operation->id(), REMOVABLE_SIMULATE); 5188 AddSimulate(operation->id(), REMOVABLE_SIMULATE);
5167 } 5189 }
5168 5190
5169 return BuildStoreNamed(prop, expr->id(), expr->position(), 5191 return BuildStoreNamed(prop, expr->id(), expr->position(),
5170 expr->AssignmentId(), prop, object, instr); 5192 expr->AssignmentId(), prop, object, instr, instr);
5171 } else { 5193 } else {
5172 // Keyed property. 5194 // Keyed property.
5173 CHECK_ALIVE(VisitForValue(prop->obj())); 5195 CHECK_ALIVE(VisitForValue(prop->obj()));
5174 CHECK_ALIVE(VisitForValue(prop->key())); 5196 CHECK_ALIVE(VisitForValue(prop->key()));
5175 HValue* obj = environment()->ExpressionStackAt(1); 5197 HValue* obj = environment()->ExpressionStackAt(1);
5176 HValue* key = environment()->ExpressionStackAt(0); 5198 HValue* key = environment()->ExpressionStackAt(0);
5177 5199
5178 bool has_side_effects = false; 5200 bool has_side_effects = false;
5179 HValue* load = HandleKeyedElementAccess( 5201 HValue* load = HandleKeyedElementAccess(
5180 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition, 5202 obj, key, NULL, prop, prop->LoadId(), RelocInfo::kNoPosition,
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
5572 HValue* val, 5594 HValue* val,
5573 Expression* prop, 5595 Expression* prop,
5574 BailoutId ast_id, 5596 BailoutId ast_id,
5575 int position, 5597 int position,
5576 bool is_store, 5598 bool is_store,
5577 KeyedAccessStoreMode store_mode, 5599 KeyedAccessStoreMode store_mode,
5578 bool* has_side_effects) { 5600 bool* has_side_effects) {
5579 *has_side_effects = false; 5601 *has_side_effects = false;
5580 BuildCheckHeapObject(object); 5602 BuildCheckHeapObject(object);
5581 SmallMapList* maps = prop->GetReceiverTypes(); 5603 SmallMapList* maps = prop->GetReceiverTypes();
5582 bool todo_external_array = false;
5583 5604
5584 if (!is_store) { 5605 if (!is_store) {
5585 HInstruction* consolidated_load = 5606 HInstruction* consolidated_load =
5586 TryBuildConsolidatedElementLoad(object, key, val, maps); 5607 TryBuildConsolidatedElementLoad(object, key, val, maps);
5587 if (consolidated_load != NULL) { 5608 if (consolidated_load != NULL) {
5588 *has_side_effects |= consolidated_load->HasObservableSideEffects(); 5609 *has_side_effects |= consolidated_load->HasObservableSideEffects();
5589 if (position != RelocInfo::kNoPosition) { 5610 if (position != RelocInfo::kNoPosition) {
5590 consolidated_load->set_position(position); 5611 consolidated_load->set_position(position);
5591 } 5612 }
5592 return consolidated_load; 5613 return consolidated_load;
5593 } 5614 }
5594 } 5615 }
5595 5616
5596 static const int kNumElementTypes = kElementsKindCount;
5597 bool type_todo[kNumElementTypes];
5598 for (int i = 0; i < kNumElementTypes; ++i) {
5599 type_todo[i] = false;
5600 }
5601
5602 // Elements_kind transition support. 5617 // Elements_kind transition support.
5603 MapHandleList transition_target(maps->length()); 5618 MapHandleList transition_target(maps->length());
5604 // Collect possible transition targets. 5619 // Collect possible transition targets.
5605 MapHandleList possible_transitioned_maps(maps->length()); 5620 MapHandleList possible_transitioned_maps(maps->length());
5606 for (int i = 0; i < maps->length(); ++i) { 5621 for (int i = 0; i < maps->length(); ++i) {
5607 Handle<Map> map = maps->at(i); 5622 Handle<Map> map = maps->at(i);
5608 ElementsKind elements_kind = map->elements_kind(); 5623 ElementsKind elements_kind = map->elements_kind();
5609 if (IsFastElementsKind(elements_kind) && 5624 if (IsFastElementsKind(elements_kind) &&
5610 elements_kind != GetInitialFastElementsKind()) { 5625 elements_kind != GetInitialFastElementsKind()) {
5611 possible_transitioned_maps.Add(map); 5626 possible_transitioned_maps.Add(map);
5612 } 5627 }
5613 } 5628 }
5614 // Get transition target for each map (NULL == no transition). 5629 // Get transition target for each map (NULL == no transition).
5615 for (int i = 0; i < maps->length(); ++i) { 5630 for (int i = 0; i < maps->length(); ++i) {
5616 Handle<Map> map = maps->at(i); 5631 Handle<Map> map = maps->at(i);
5617 Handle<Map> transitioned_map = 5632 Handle<Map> transitioned_map =
5618 map->FindTransitionedMap(&possible_transitioned_maps); 5633 map->FindTransitionedMap(&possible_transitioned_maps);
5619 transition_target.Add(transitioned_map); 5634 transition_target.Add(transitioned_map);
5620 } 5635 }
5621 5636
5622 int num_untransitionable_maps = 0; 5637 MapHandleList untransitionable_maps(maps->length());
5623 Handle<Map> untransitionable_map;
5624 HTransitionElementsKind* transition = NULL; 5638 HTransitionElementsKind* transition = NULL;
5625 for (int i = 0; i < maps->length(); ++i) { 5639 for (int i = 0; i < maps->length(); ++i) {
5626 Handle<Map> map = maps->at(i); 5640 Handle<Map> map = maps->at(i);
5627 ASSERT(map->IsMap()); 5641 ASSERT(map->IsMap());
5628 if (!transition_target.at(i).is_null()) { 5642 if (!transition_target.at(i).is_null()) {
5629 ASSERT(Map::IsValidElementsTransition( 5643 ASSERT(Map::IsValidElementsTransition(
5630 map->elements_kind(), 5644 map->elements_kind(),
5631 transition_target.at(i)->elements_kind())); 5645 transition_target.at(i)->elements_kind()));
5632 HValue* context = environment()->LookupContext(); 5646 HValue* context = environment()->LookupContext();
5633 transition = Add<HTransitionElementsKind>(context, object, map, 5647 transition = Add<HTransitionElementsKind>(context, object, map,
5634 transition_target.at(i)); 5648 transition_target.at(i));
5635 } else { 5649 } else {
5636 type_todo[map->elements_kind()] = true; 5650 untransitionable_maps.Add(map);
5637 if (IsExternalArrayElementsKind(map->elements_kind())) {
5638 todo_external_array = true;
5639 }
5640 num_untransitionable_maps++;
5641 untransitionable_map = map;
5642 } 5651 }
5643 } 5652 }
5644 5653
5645 // If only one map is left after transitioning, handle this case 5654 // If only one map is left after transitioning, handle this case
5646 // monomorphically. 5655 // monomorphically.
5647 ASSERT(num_untransitionable_maps >= 1); 5656 ASSERT(untransitionable_maps.length() >= 1);
5648 if (num_untransitionable_maps == 1) { 5657 if (untransitionable_maps.length() == 1) {
5658 Handle<Map> untransitionable_map = untransitionable_maps[0];
5649 HInstruction* instr = NULL; 5659 HInstruction* instr = NULL;
5650 if (untransitionable_map->has_slow_elements_kind()) { 5660 if (untransitionable_map->has_slow_elements_kind()) {
5651 instr = AddInstruction(is_store ? BuildStoreKeyedGeneric(object, key, val) 5661 instr = AddInstruction(is_store ? BuildStoreKeyedGeneric(object, key, val)
5652 : BuildLoadKeyedGeneric(object, key)); 5662 : BuildLoadKeyedGeneric(object, key));
5653 } else { 5663 } else {
5654 instr = BuildMonomorphicElementAccess( 5664 instr = BuildMonomorphicElementAccess(
5655 object, key, val, transition, untransitionable_map, is_store, 5665 object, key, val, transition, untransitionable_map, is_store,
5656 store_mode); 5666 store_mode);
5657 } 5667 }
5658 *has_side_effects |= instr->HasObservableSideEffects(); 5668 *has_side_effects |= instr->HasObservableSideEffects();
5659 if (position != RelocInfo::kNoPosition) instr->set_position(position); 5669 if (position != RelocInfo::kNoPosition) instr->set_position(position);
5660 return is_store ? NULL : instr; 5670 return is_store ? NULL : instr;
5661 } 5671 }
5662 5672
5663 HInstruction* checkspec = 5673 HInstruction* checkspec =
5664 AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone())); 5674 AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone()));
5665 HBasicBlock* join = graph()->CreateBasicBlock(); 5675 HBasicBlock* join = graph()->CreateBasicBlock();
5666 5676
5667 HInstruction* elements_kind_instr = Add<HElementsKind>(object);
5668 HInstruction* elements = AddLoadElements(object, checkspec); 5677 HInstruction* elements = AddLoadElements(object, checkspec);
5669 HLoadExternalArrayPointer* external_elements = NULL;
5670 HInstruction* checked_key = NULL;
5671 5678
5672 // Generated code assumes that FAST_* and DICTIONARY_ELEMENTS ElementsKinds 5679 for (int i = 0; i < untransitionable_maps.length(); ++i) {
5673 // are handled before external arrays. 5680 Handle<Map> map = untransitionable_maps[i];
5674 STATIC_ASSERT(FAST_SMI_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); 5681 ElementsKind elements_kind = map->elements_kind();
5675 STATIC_ASSERT(FAST_HOLEY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); 5682 HBasicBlock* this_map = graph()->CreateBasicBlock();
5676 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); 5683 HBasicBlock* other_map = graph()->CreateBasicBlock();
5677 STATIC_ASSERT(DICTIONARY_ELEMENTS < FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); 5684 HCompareMap* mapcompare =
5685 new(zone()) HCompareMap(object, map, this_map, other_map);
5686 current_block()->Finish(mapcompare);
5678 5687
5679 for (ElementsKind elements_kind = FIRST_ELEMENTS_KIND; 5688 set_current_block(this_map);
5680 elements_kind <= LAST_ELEMENTS_KIND; 5689 HInstruction* checked_key = NULL;
5681 elements_kind = ElementsKind(elements_kind + 1)) { 5690 HInstruction* access = NULL;
5682 // After having handled FAST_* and DICTIONARY_ELEMENTS, we need to add some 5691 if (IsFastElementsKind(elements_kind)) {
5683 // code that's executed for all external array cases. 5692 if (is_store && !IsFastDoubleElementsKind(elements_kind)) {
5684 STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == 5693 AddInstruction(HCheckMaps::New(
5685 LAST_ELEMENTS_KIND); 5694 elements, isolate()->factory()->fixed_array_map(),
5686 if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND 5695 zone(), mapcompare));
5687 && todo_external_array) { 5696 }
5697 if (map->IsJSArray()) {
5698 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(),
5699 mapcompare, Representation::Smi());
5700 length->set_type(HType::Smi());
5701 checked_key = Add<HBoundsCheck>(key, length);
5702 } else {
5703 HInstruction* length = AddLoadFixedArrayLength(elements);
5704 checked_key = Add<HBoundsCheck>(key, length);
5705 }
5706 access = AddFastElementAccess(
5707 elements, checked_key, val, mapcompare,
5708 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE);
5709 } else if (IsDictionaryElementsKind(elements_kind)) {
5710 if (is_store) {
5711 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val));
5712 } else {
5713 access = AddInstruction(BuildLoadKeyedGeneric(object, key));
5714 }
5715 } else {
5716 ASSERT(IsExternalArrayElementsKind(elements_kind));
5688 HInstruction* length = AddLoadFixedArrayLength(elements); 5717 HInstruction* length = AddLoadFixedArrayLength(elements);
5689 checked_key = Add<HBoundsCheck>(key, length); 5718 checked_key = Add<HBoundsCheck>(key, length);
5690 external_elements = Add<HLoadExternalArrayPointer>(elements); 5719 HLoadExternalArrayPointer* external_elements =
5720 Add<HLoadExternalArrayPointer>(elements);
5721 access = AddExternalArrayElementAccess(
5722 external_elements, checked_key, val,
5723 mapcompare, elements_kind, is_store);
5691 } 5724 }
5692 if (type_todo[elements_kind]) { 5725 *has_side_effects |= access->HasObservableSideEffects();
5693 HBasicBlock* if_true = graph()->CreateBasicBlock(); 5726 // The caller will use has_side_effects and add a correct Simulate.
5694 HBasicBlock* if_false = graph()->CreateBasicBlock(); 5727 access->SetFlag(HValue::kHasNoObservableSideEffects);
5695 HCompareConstantEqAndBranch* elements_kind_branch = 5728 if (position != RelocInfo::kNoPosition) access->set_position(position);
5696 new(zone()) HCompareConstantEqAndBranch( 5729 if (!is_store) {
5697 elements_kind_instr, elements_kind, Token::EQ_STRICT); 5730 Push(access);
5698 elements_kind_branch->SetSuccessorAt(0, if_true);
5699 elements_kind_branch->SetSuccessorAt(1, if_false);
5700 current_block()->Finish(elements_kind_branch);
5701
5702 set_current_block(if_true);
5703 HInstruction* access;
5704 if (IsFastElementsKind(elements_kind)) {
5705 if (is_store && !IsFastDoubleElementsKind(elements_kind)) {
5706 AddInstruction(HCheckMaps::New(
5707 elements, isolate()->factory()->fixed_array_map(),
5708 zone(), elements_kind_branch));
5709 }
5710 // TODO(jkummerow): The need for these two blocks could be avoided
5711 // in one of two ways:
5712 // (1) Introduce ElementsKinds for JSArrays that are distinct from
5713 // those for fast objects.
5714 // (2) Put the common instructions into a third "join" block. This
5715 // requires additional AST IDs that we can deopt to from inside
5716 // that join block. They must be added to the Property class (when
5717 // it's a keyed property) and registered in the full codegen.
5718 HBasicBlock* if_jsarray = graph()->CreateBasicBlock();
5719 HBasicBlock* if_fastobject = graph()->CreateBasicBlock();
5720 HHasInstanceTypeAndBranch* typecheck =
5721 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE);
5722 typecheck->SetSuccessorAt(0, if_jsarray);
5723 typecheck->SetSuccessorAt(1, if_fastobject);
5724 current_block()->Finish(typecheck);
5725
5726 set_current_block(if_jsarray);
5727 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(),
5728 typecheck, Representation::Smi());
5729 length->set_type(HType::Smi());
5730
5731 checked_key = Add<HBoundsCheck>(key, length);
5732 access = AddInstruction(BuildFastElementAccess(
5733 elements, checked_key, val, elements_kind_branch,
5734 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE));
5735 if (!is_store) {
5736 Push(access);
5737 }
5738
5739 *has_side_effects |= access->HasObservableSideEffects();
5740 // The caller will use has_side_effects and add correct Simulate.
5741 access->SetFlag(HValue::kHasNoObservableSideEffects);
5742 if (position != -1) {
5743 access->set_position(position);
5744 }
5745 if_jsarray->GotoNoSimulate(join);
5746
5747 set_current_block(if_fastobject);
5748 length = AddLoadFixedArrayLength(elements);
5749 checked_key = Add<HBoundsCheck>(key, length);
5750 access = AddInstruction(BuildFastElementAccess(
5751 elements, checked_key, val, elements_kind_branch,
5752 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE));
5753 } else if (elements_kind == DICTIONARY_ELEMENTS) {
5754 if (is_store) {
5755 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val));
5756 } else {
5757 access = AddInstruction(BuildLoadKeyedGeneric(object, key));
5758 }
5759 } else { // External array elements.
5760 access = AddInstruction(BuildExternalArrayElementAccess(
5761 external_elements, checked_key, val,
5762 elements_kind_branch, elements_kind, is_store));
5763 }
5764 *has_side_effects |= access->HasObservableSideEffects();
5765 // The caller will use has_side_effects and add correct Simulate.
5766 access->SetFlag(HValue::kHasNoObservableSideEffects);
5767 if (position != RelocInfo::kNoPosition) access->set_position(position);
5768 if (!is_store) {
5769 Push(access);
5770 }
5771 current_block()->GotoNoSimulate(join);
5772 set_current_block(if_false);
5773 } 5731 }
5732 current_block()->GotoNoSimulate(join);
5733 set_current_block(other_map);
5774 } 5734 }
5775 5735
5776 // Deopt if none of the cases matched. 5736 // Deopt if none of the cases matched.
5777 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses); 5737 current_block()->FinishExitWithDeoptimization(HDeoptimize::kNoUses);
5778 set_current_block(join); 5738 set_current_block(join);
5779 return is_store ? NULL : Pop(); 5739 return is_store ? NULL : Pop();
5780 } 5740 }
5781 5741
5782 5742
5783 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( 5743 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
6335 CompilationInfo* outer_info = current_info(); 6295 CompilationInfo* outer_info = current_info();
6336 if (target->context() != outer_info->closure()->context() || 6296 if (target->context() != outer_info->closure()->context() ||
6337 outer_info->scope()->contains_with() || 6297 outer_info->scope()->contains_with() ||
6338 outer_info->scope()->num_heap_slots() > 0) { 6298 outer_info->scope()->num_heap_slots() > 0) {
6339 TraceInline(target, caller, "target requires context change"); 6299 TraceInline(target, caller, "target requires context change");
6340 return false; 6300 return false;
6341 } 6301 }
6342 #endif 6302 #endif
6343 6303
6344 6304
6345 // Don't inline deeper than kMaxInliningLevels calls. 6305 // Don't inline deeper than the maximum number of inlining levels.
6346 HEnvironment* env = environment(); 6306 HEnvironment* env = environment();
6347 int current_level = 1; 6307 int current_level = 1;
6348 while (env->outer() != NULL) { 6308 while (env->outer() != NULL) {
6349 if (current_level == Compiler::kMaxInliningLevels) { 6309 if (current_level == FLAG_max_inlining_levels) {
6350 TraceInline(target, caller, "inline depth limit reached"); 6310 TraceInline(target, caller, "inline depth limit reached");
6351 return false; 6311 return false;
6352 } 6312 }
6353 if (env->outer()->frame_type() == JS_FUNCTION) { 6313 if (env->outer()->frame_type() == JS_FUNCTION) {
6354 current_level++; 6314 current_level++;
6355 } 6315 }
6356 env = env->outer(); 6316 env = env->outer();
6357 } 6317 }
6358 6318
6359 // Don't inline recursive functions. 6319 // Don't inline recursive functions.
(...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after
7393 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { 7353 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
7394 ASSERT(!HasStackOverflow()); 7354 ASSERT(!HasStackOverflow());
7395 ASSERT(current_block() != NULL); 7355 ASSERT(current_block() != NULL);
7396 ASSERT(current_block()->HasPredecessor()); 7356 ASSERT(current_block()->HasPredecessor());
7397 if (expr->is_jsruntime()) { 7357 if (expr->is_jsruntime()) {
7398 return Bailout("call to a JavaScript runtime function"); 7358 return Bailout("call to a JavaScript runtime function");
7399 } 7359 }
7400 7360
7401 const Runtime::Function* function = expr->function(); 7361 const Runtime::Function* function = expr->function();
7402 ASSERT(function != NULL); 7362 ASSERT(function != NULL);
7403
7404 if (static_cast<int>(function->function_id)
7405 == static_cast<int>(Runtime::kNeverOptimize)
7406 && expr->arguments()->length() == 0) {
7407 // %NeverOptimize() without arguments marks the caller as never optimize.
7408 return Bailout("function marked itself as never optimize");
7409 }
7410
7411 if (function->intrinsic_type == Runtime::INLINE) { 7363 if (function->intrinsic_type == Runtime::INLINE) {
7412 ASSERT(expr->name()->length() > 0); 7364 ASSERT(expr->name()->length() > 0);
7413 ASSERT(expr->name()->Get(0) == '_'); 7365 ASSERT(expr->name()->Get(0) == '_');
7414 // Call to an inline function. 7366 // Call to an inline function.
7415 int lookup_index = static_cast<int>(function->function_id) - 7367 int lookup_index = static_cast<int>(function->function_id) -
7416 static_cast<int>(Runtime::kFirstInlineFunction); 7368 static_cast<int>(Runtime::kFirstInlineFunction);
7417 ASSERT(lookup_index >= 0); 7369 ASSERT(lookup_index >= 0);
7418 ASSERT(static_cast<size_t>(lookup_index) < 7370 ASSERT(static_cast<size_t>(lookup_index) <
7419 ARRAY_SIZE(kInlineFunctionGenerators)); 7371 ARRAY_SIZE(kInlineFunctionGenerators));
7420 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; 7372 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index];
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
7715 } else if (types != NULL && types->length() > 1) { 7667 } else if (types != NULL && types->length() > 1) {
7716 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); 7668 load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name);
7717 } 7669 }
7718 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); 7670 if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop);
7719 PushAndAdd(load); 7671 PushAndAdd(load);
7720 if (load->HasObservableSideEffects()) { 7672 if (load->HasObservableSideEffects()) {
7721 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); 7673 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE);
7722 } 7674 }
7723 7675
7724 after = BuildIncrement(returns_original_input, expr); 7676 after = BuildIncrement(returns_original_input, expr);
7725 7677 HValue* result = returns_original_input ? Pop() : after;
7726 HValue* result = returns_original_input ? Pop() : NULL;
7727 7678
7728 return BuildStoreNamed(prop, expr->id(), expr->position(), 7679 return BuildStoreNamed(prop, expr->id(), expr->position(),
7729 expr->AssignmentId(), prop, object, after, result); 7680 expr->AssignmentId(), prop, object, after, result);
7730 } else { 7681 } else {
7731 // Keyed property. 7682 // Keyed property.
7732 if (returns_original_input) Push(graph()->GetConstantUndefined()); 7683 if (returns_original_input) Push(graph()->GetConstantUndefined());
7733 7684
7734 CHECK_ALIVE(VisitForValue(prop->obj())); 7685 CHECK_ALIVE(VisitForValue(prop->obj()));
7735 CHECK_ALIVE(VisitForValue(prop->key())); 7686 CHECK_ALIVE(VisitForValue(prop->key()));
7736 HValue* obj = environment()->ExpressionStackAt(1); 7687 HValue* obj = environment()->ExpressionStackAt(1);
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
8085 CHECK_ALIVE(VisitForValue(expr->right())); 8036 CHECK_ALIVE(VisitForValue(expr->right()));
8086 HValue* right = Pop(); 8037 HValue* right = Pop();
8087 HValue* left = Pop(); 8038 HValue* left = Pop();
8088 HInstruction* instr = BuildBinaryOperation(expr, left, right); 8039 HInstruction* instr = BuildBinaryOperation(expr, left, right);
8089 instr->set_position(expr->position()); 8040 instr->set_position(expr->position());
8090 return ast_context()->ReturnInstruction(instr, expr->id()); 8041 return ast_context()->ReturnInstruction(instr, expr->id());
8091 } 8042 }
8092 8043
8093 8044
8094 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, 8045 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr,
8095 HTypeof* typeof_expr, 8046 Expression* sub_expr,
8096 Handle<String> check) { 8047 Handle<String> check) {
8097 // Note: The HTypeof itself is removed during canonicalization, if possible. 8048 CHECK_ALIVE(VisitForTypeOf(sub_expr));
8098 HValue* value = typeof_expr->value(); 8049 HValue* value = Pop();
8099 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check); 8050 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check);
8100 instr->set_position(expr->position()); 8051 instr->set_position(expr->position());
8101 return ast_context()->ReturnControl(instr, expr->id()); 8052 return ast_context()->ReturnControl(instr, expr->id());
8102 } 8053 }
8103 8054
8104 8055
8105 static bool MatchLiteralCompareNil(HValue* left,
8106 Token::Value op,
8107 HValue* right,
8108 Handle<Object> nil,
8109 HValue** expr) {
8110 if (left->IsConstant() &&
8111 HConstant::cast(left)->handle().is_identical_to(nil) &&
8112 Token::IsEqualityOp(op)) {
8113 *expr = right;
8114 return true;
8115 }
8116 return false;
8117 }
8118
8119
8120 static bool MatchLiteralCompareTypeof(HValue* left,
8121 Token::Value op,
8122 HValue* right,
8123 HTypeof** typeof_expr,
8124 Handle<String>* check) {
8125 if (left->IsTypeof() &&
8126 Token::IsEqualityOp(op) &&
8127 right->IsConstant() &&
8128 HConstant::cast(right)->handle()->IsString()) {
8129 *typeof_expr = HTypeof::cast(left);
8130 *check = Handle<String>::cast(HConstant::cast(right)->handle());
8131 return true;
8132 }
8133 return false;
8134 }
8135
8136
8137 static bool IsLiteralCompareTypeof(HValue* left,
8138 Token::Value op,
8139 HValue* right,
8140 HTypeof** typeof_expr,
8141 Handle<String>* check) {
8142 return MatchLiteralCompareTypeof(left, op, right, typeof_expr, check) ||
8143 MatchLiteralCompareTypeof(right, op, left, typeof_expr, check);
8144 }
8145
8146
8147 static bool IsLiteralCompareNil(HValue* left,
8148 Token::Value op,
8149 HValue* right,
8150 Handle<Object> nil,
8151 HValue** expr) {
8152 return MatchLiteralCompareNil(left, op, right, nil, expr) ||
8153 MatchLiteralCompareNil(right, op, left, nil, expr);
8154 }
8155
8156
8157 static bool IsLiteralCompareBool(HValue* left, 8056 static bool IsLiteralCompareBool(HValue* left,
8158 Token::Value op, 8057 Token::Value op,
8159 HValue* right) { 8058 HValue* right) {
8160 return op == Token::EQ_STRICT && 8059 return op == Token::EQ_STRICT &&
8161 ((left->IsConstant() && HConstant::cast(left)->handle()->IsBoolean()) || 8060 ((left->IsConstant() && HConstant::cast(left)->handle()->IsBoolean()) ||
8162 (right->IsConstant() && HConstant::cast(right)->handle()->IsBoolean())); 8061 (right->IsConstant() && HConstant::cast(right)->handle()->IsBoolean()));
8163 } 8062 }
8164 8063
8165 8064
8166 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 8065 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
8167 ASSERT(!HasStackOverflow()); 8066 ASSERT(!HasStackOverflow());
8168 ASSERT(current_block() != NULL); 8067 ASSERT(current_block() != NULL);
8169 ASSERT(current_block()->HasPredecessor()); 8068 ASSERT(current_block()->HasPredecessor());
8069
8070 // Check for a few fast cases. The AST visiting behavior must be in sync
8071 // with the full codegen: We don't push both left and right values onto
8072 // the expression stack when one side is a special-case literal.
8073 Expression* sub_expr = NULL;
8074 Handle<String> check;
8075 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
8076 return HandleLiteralCompareTypeof(expr, sub_expr, check);
8077 }
8078 if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) {
8079 return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue);
8080 }
8081 if (expr->IsLiteralCompareNull(&sub_expr)) {
8082 return HandleLiteralCompareNil(expr, sub_expr, kNullValue);
8083 }
8084
8170 if (IsClassOfTest(expr)) { 8085 if (IsClassOfTest(expr)) {
8171 CallRuntime* call = expr->left()->AsCallRuntime(); 8086 CallRuntime* call = expr->left()->AsCallRuntime();
8172 ASSERT(call->arguments()->length() == 1); 8087 ASSERT(call->arguments()->length() == 1);
8173 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 8088 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
8174 HValue* value = Pop(); 8089 HValue* value = Pop();
8175 Literal* literal = expr->right()->AsLiteral(); 8090 Literal* literal = expr->right()->AsLiteral();
8176 Handle<String> rhs = Handle<String>::cast(literal->value()); 8091 Handle<String> rhs = Handle<String>::cast(literal->value());
8177 HClassOfTestAndBranch* instr = 8092 HClassOfTestAndBranch* instr =
8178 new(zone()) HClassOfTestAndBranch(value, rhs); 8093 new(zone()) HClassOfTestAndBranch(value, rhs);
8179 instr->set_position(expr->position()); 8094 instr->set_position(expr->position());
8180 return ast_context()->ReturnControl(instr, expr->id()); 8095 return ast_context()->ReturnControl(instr, expr->id());
8181 } 8096 }
8182 8097
8183 Handle<Type> left_type = expr->left()->bounds().lower; 8098 Handle<Type> left_type = expr->left()->bounds().lower;
8184 Handle<Type> right_type = expr->right()->bounds().lower; 8099 Handle<Type> right_type = expr->right()->bounds().lower;
8185 Handle<Type> combined_type = expr->combined_type(); 8100 Handle<Type> combined_type = expr->combined_type();
8186 Representation combined_rep = Representation::FromType(combined_type); 8101 Representation combined_rep = Representation::FromType(combined_type);
8187 Representation left_rep = Representation::FromType(left_type); 8102 Representation left_rep = Representation::FromType(left_type);
8188 Representation right_rep = Representation::FromType(right_type); 8103 Representation right_rep = Representation::FromType(right_type);
8189 8104
8190 CHECK_ALIVE(VisitForValue(expr->left())); 8105 CHECK_ALIVE(VisitForValue(expr->left()));
8191 CHECK_ALIVE(VisitForValue(expr->right())); 8106 CHECK_ALIVE(VisitForValue(expr->right()));
8192 8107
8193 HValue* context = environment()->LookupContext(); 8108 HValue* context = environment()->LookupContext();
8194 HValue* right = Pop(); 8109 HValue* right = Pop();
8195 HValue* left = Pop(); 8110 HValue* left = Pop();
8196 Token::Value op = expr->op(); 8111 Token::Value op = expr->op();
8197 8112
8198 HTypeof* typeof_expr = NULL;
8199 Handle<String> check;
8200 if (IsLiteralCompareTypeof(left, op, right, &typeof_expr, &check)) {
8201 return HandleLiteralCompareTypeof(expr, typeof_expr, check);
8202 }
8203 HValue* sub_expr = NULL;
8204 Factory* f = isolate()->factory();
8205 if (IsLiteralCompareNil(left, op, right, f->undefined_value(), &sub_expr)) {
8206 return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue);
8207 }
8208 if (IsLiteralCompareNil(left, op, right, f->null_value(), &sub_expr)) {
8209 return HandleLiteralCompareNil(expr, sub_expr, kNullValue);
8210 }
8211 if (IsLiteralCompareBool(left, op, right)) { 8113 if (IsLiteralCompareBool(left, op, right)) {
8212 HCompareObjectEqAndBranch* result = 8114 HCompareObjectEqAndBranch* result =
8213 new(zone()) HCompareObjectEqAndBranch(left, right); 8115 new(zone()) HCompareObjectEqAndBranch(left, right);
8214 result->set_position(expr->position()); 8116 result->set_position(expr->position());
8215 return ast_context()->ReturnControl(result, expr->id()); 8117 return ast_context()->ReturnControl(result, expr->id());
8216 } 8118 }
8217 8119
8218 if (op == Token::INSTANCEOF) { 8120 if (op == Token::INSTANCEOF) {
8219 // Check to see if the rhs of the instanceof is a global function not 8121 // Check to see if the rhs of the instanceof is a global function not
8220 // residing in new space. If it is we assume that the function will stay the 8122 // residing in new space. If it is we assume that the function will stay the
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
8327 new(zone()) HCompareNumericAndBranch(left, right, op); 8229 new(zone()) HCompareNumericAndBranch(left, right, op);
8328 result->set_observed_input_representation(left_rep, right_rep); 8230 result->set_observed_input_representation(left_rep, right_rep);
8329 result->set_position(expr->position()); 8231 result->set_position(expr->position());
8330 return ast_context()->ReturnControl(result, expr->id()); 8232 return ast_context()->ReturnControl(result, expr->id());
8331 } 8233 }
8332 } 8234 }
8333 } 8235 }
8334 8236
8335 8237
8336 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, 8238 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
8337 HValue* value, 8239 Expression* sub_expr,
8338 NilValue nil) { 8240 NilValue nil) {
8339 ASSERT(!HasStackOverflow()); 8241 ASSERT(!HasStackOverflow());
8340 ASSERT(current_block() != NULL); 8242 ASSERT(current_block() != NULL);
8341 ASSERT(current_block()->HasPredecessor()); 8243 ASSERT(current_block()->HasPredecessor());
8342 ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); 8244 ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT);
8245 CHECK_ALIVE(VisitForValue(sub_expr));
8246 HValue* value = Pop();
8343 HIfContinuation continuation; 8247 HIfContinuation continuation;
8344 if (expr->op() == Token::EQ_STRICT) { 8248 if (expr->op() == Token::EQ_STRICT) {
8345 IfBuilder if_nil(this); 8249 IfBuilder if_nil(this);
8346 if_nil.If<HCompareObjectEqAndBranch>( 8250 if_nil.If<HCompareObjectEqAndBranch>(
8347 value, (nil == kNullValue) ? graph()->GetConstantNull() 8251 value, (nil == kNullValue) ? graph()->GetConstantNull()
8348 : graph()->GetConstantUndefined()); 8252 : graph()->GetConstantUndefined());
8349 if_nil.Then(); 8253 if_nil.Then();
8350 if_nil.Else(); 8254 if_nil.Else();
8351 if_nil.CaptureContinuation(&continuation); 8255 if_nil.CaptureContinuation(&continuation);
8352 return ast_context()->ReturnContinuation(&continuation, expr->id()); 8256 return ast_context()->ReturnContinuation(&continuation, expr->id());
(...skipping 23 matching lines...) Expand all
8376 Handle<JSObject> original_boilerplate_object, 8280 Handle<JSObject> original_boilerplate_object,
8377 Handle<Object> allocation_site, 8281 Handle<Object> allocation_site,
8378 int data_size, 8282 int data_size,
8379 int pointer_size, 8283 int pointer_size,
8380 AllocationSiteMode mode) { 8284 AllocationSiteMode mode) {
8381 NoObservableSideEffectsScope no_effects(this); 8285 NoObservableSideEffectsScope no_effects(this);
8382 8286
8383 HInstruction* target = NULL; 8287 HInstruction* target = NULL;
8384 HInstruction* data_target = NULL; 8288 HInstruction* data_target = NULL;
8385 8289
8386 HAllocate::Flags flags = HAllocate::DefaultFlags(); 8290 ElementsKind kind = boilerplate_object->map()->elements_kind();
8387 8291
8388 if (isolate()->heap()->ShouldGloballyPretenure()) { 8292 if (isolate()->heap()->ShouldGloballyPretenure()) {
8389 if (data_size != 0) { 8293 if (data_size != 0) {
8390 HAllocate::Flags data_flags = 8294 HAllocate::Flags data_flags =
8391 static_cast<HAllocate::Flags>(HAllocate::DefaultFlags() | 8295 static_cast<HAllocate::Flags>(HAllocate::DefaultFlags(kind) |
8392 HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE); 8296 HAllocate::CAN_ALLOCATE_IN_OLD_DATA_SPACE);
8393 HValue* size_in_bytes = Add<HConstant>(data_size); 8297 HValue* size_in_bytes = Add<HConstant>(data_size);
8394 data_target = Add<HAllocate>(context, size_in_bytes, 8298 data_target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(),
8395 HType::JSObject(), data_flags); 8299 data_flags);
8396 Handle<Map> free_space_map = isolate()->factory()->free_space_map(); 8300 Handle<Map> free_space_map = isolate()->factory()->free_space_map();
8397 AddStoreMapConstant(data_target, free_space_map); 8301 AddStoreMapConstant(data_target, free_space_map);
8398 HObjectAccess access = 8302 HObjectAccess access =
8399 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset); 8303 HObjectAccess::ForJSObjectOffset(FreeSpace::kSizeOffset);
8400 AddStore(data_target, access, size_in_bytes); 8304 AddStore(data_target, access, size_in_bytes);
8401 } 8305 }
8402 if (pointer_size != 0) { 8306 if (pointer_size != 0) {
8403 flags = static_cast<HAllocate::Flags>( 8307 HAllocate::Flags pointer_flags =
8404 flags | HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE); 8308 static_cast<HAllocate::Flags>(HAllocate::DefaultFlags() |
8309 HAllocate::CAN_ALLOCATE_IN_OLD_POINTER_SPACE);
8405 HValue* size_in_bytes = Add<HConstant>(pointer_size); 8310 HValue* size_in_bytes = Add<HConstant>(pointer_size);
8406 target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), flags); 8311 target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(),
8312 pointer_flags);
8407 } 8313 }
8408 } else { 8314 } else {
8315 HAllocate::Flags flags = HAllocate::DefaultFlags(kind);
8409 HValue* size_in_bytes = Add<HConstant>(data_size + pointer_size); 8316 HValue* size_in_bytes = Add<HConstant>(data_size + pointer_size);
8410 target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), flags); 8317 target = Add<HAllocate>(context, size_in_bytes, HType::JSObject(), flags);
8411 } 8318 }
8412 8319
8413 int offset = 0; 8320 int offset = 0;
8414 int data_offset = 0; 8321 int data_offset = 0;
8415 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object, 8322 BuildEmitDeepCopy(boilerplate_object, original_boilerplate_object,
8416 allocation_site, target, &offset, data_target, 8323 allocation_site, target, &offset, data_target,
8417 &data_offset, mode); 8324 &data_offset, mode);
8418 return target; 8325 return target;
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
8482 if (boilerplate_object->map()->NumberOfFields() != 0) { 8389 if (boilerplate_object->map()->NumberOfFields() != 0) {
8483 HValue* object_properties = 8390 HValue* object_properties =
8484 Add<HInnerAllocatedObject>(target, object_offset); 8391 Add<HInnerAllocatedObject>(target, object_offset);
8485 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, 8392 BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object,
8486 object_properties, target, offset, data_target, data_offset); 8393 object_properties, target, offset, data_target, data_offset);
8487 } 8394 }
8488 8395
8489 // Create allocation site info. 8396 // Create allocation site info.
8490 if (mode == TRACK_ALLOCATION_SITE && 8397 if (mode == TRACK_ALLOCATION_SITE &&
8491 boilerplate_object->map()->CanTrackAllocationSite()) { 8398 boilerplate_object->map()->CanTrackAllocationSite()) {
8492 elements_offset += AllocationSiteInfo::kSize; 8399 elements_offset += AllocationMemento::kSize;
8493 *offset += AllocationSiteInfo::kSize; 8400 *offset += AllocationMemento::kSize;
8494 BuildCreateAllocationSiteInfo(target, JSArray::kSize, allocation_site); 8401 BuildCreateAllocationMemento(target, JSArray::kSize, allocation_site);
8495 } 8402 }
8496 } 8403 }
8497 8404
8498 8405
8499 HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader( 8406 HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader(
8500 Handle<JSObject> boilerplate_object, 8407 Handle<JSObject> boilerplate_object,
8501 HInstruction* target, 8408 HInstruction* target,
8502 HInstruction* data_target, 8409 HInstruction* data_target,
8503 int object_offset, 8410 int object_offset,
8504 int elements_offset, 8411 int elements_offset,
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
9157 HValue* context = environment()->LookupContext(); 9064 HValue* context = environment()->LookupContext();
9158 HGlobalObject* global_object = Add<HGlobalObject>(context); 9065 HGlobalObject* global_object = Add<HGlobalObject>(context);
9159 HRandom* result = new(zone()) HRandom(global_object); 9066 HRandom* result = new(zone()) HRandom(global_object);
9160 return ast_context()->ReturnInstruction(result, call->id()); 9067 return ast_context()->ReturnInstruction(result, call->id());
9161 } 9068 }
9162 9069
9163 9070
9164 // Fast support for StringAdd. 9071 // Fast support for StringAdd.
9165 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { 9072 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) {
9166 ASSERT_EQ(2, call->arguments()->length()); 9073 ASSERT_EQ(2, call->arguments()->length());
9167 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9074 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
9075 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
9076 HValue* right = Pop();
9077 HValue* left = Pop();
9168 HValue* context = environment()->LookupContext(); 9078 HValue* context = environment()->LookupContext();
9169 HCallStub* result = new(zone()) HCallStub(context, CodeStub::StringAdd, 2); 9079 HInstruction* result = HStringAdd::New(
9170 Drop(2); 9080 zone(), context, left, right, STRING_ADD_CHECK_BOTH);
9171 return ast_context()->ReturnInstruction(result, call->id()); 9081 return ast_context()->ReturnInstruction(result, call->id());
9172 } 9082 }
9173 9083
9174 9084
9175 // Fast support for SubString. 9085 // Fast support for SubString.
9176 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { 9086 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) {
9177 ASSERT_EQ(3, call->arguments()->length()); 9087 ASSERT_EQ(3, call->arguments()->length());
9178 CHECK_ALIVE(VisitArgumentList(call->arguments())); 9088 CHECK_ALIVE(VisitArgumentList(call->arguments()));
9179 HValue* context = environment()->LookupContext(); 9089 HValue* context = environment()->LookupContext();
9180 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3); 9090 HCallStub* result = new(zone()) HCallStub(context, CodeStub::SubString, 3);
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after
9996 if (ShouldProduceTraceOutput()) { 9906 if (ShouldProduceTraceOutput()) {
9997 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 9907 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
9998 } 9908 }
9999 9909
10000 #ifdef DEBUG 9910 #ifdef DEBUG
10001 graph_->Verify(false); // No full verify. 9911 graph_->Verify(false); // No full verify.
10002 #endif 9912 #endif
10003 } 9913 }
10004 9914
10005 } } // namespace v8::internal 9915 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698