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 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1071 HValue* current_capacity = AddLoadFixedArrayLength(elements); | 1071 HValue* current_capacity = AddLoadFixedArrayLength(elements); |
1072 | 1072 |
1073 IfBuilder capacity_checker(this); | 1073 IfBuilder capacity_checker(this); |
1074 | 1074 |
1075 capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity, | 1075 capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity, |
1076 Token::GTE); | 1076 Token::GTE); |
1077 capacity_checker.Then(); | 1077 capacity_checker.Then(); |
1078 | 1078 |
1079 HValue* context = environment()->LookupContext(); | 1079 HValue* context = environment()->LookupContext(); |
1080 | 1080 |
| 1081 HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap)); |
| 1082 HValue* max_capacity = AddInstruction( |
| 1083 HAdd::New(zone, context, current_capacity, max_gap)); |
| 1084 IfBuilder key_checker(this); |
| 1085 key_checker.If<HCompareNumericAndBranch>(key, max_capacity, Token::LT); |
| 1086 key_checker.Then(); |
| 1087 key_checker.ElseDeopt(); |
| 1088 key_checker.End(); |
| 1089 |
1081 HValue* new_capacity = BuildNewElementsCapacity(context, key); | 1090 HValue* new_capacity = BuildNewElementsCapacity(context, key); |
1082 | |
1083 HValue* new_elements = BuildGrowElementsCapacity(object, elements, | 1091 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
1084 kind, kind, length, | 1092 kind, kind, length, |
1085 new_capacity); | 1093 new_capacity); |
1086 | 1094 |
1087 environment()->Push(new_elements); | 1095 environment()->Push(new_elements); |
1088 capacity_checker.Else(); | 1096 capacity_checker.Else(); |
1089 | 1097 |
1090 environment()->Push(elements); | 1098 environment()->Push(elements); |
1091 capacity_checker.End(); | 1099 capacity_checker.End(); |
1092 | 1100 |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1330 | 1338 |
1331 AddStoreMapConstant(elements, map); | 1339 AddStoreMapConstant(elements, map); |
1332 AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity); | 1340 AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity); |
1333 } | 1341 } |
1334 | 1342 |
1335 | 1343 |
1336 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( | 1344 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( |
1337 HValue* context, | 1345 HValue* context, |
1338 ElementsKind kind, | 1346 ElementsKind kind, |
1339 HValue* capacity) { | 1347 HValue* capacity) { |
| 1348 // The HForceRepresentation is to prevent possible deopt on int-smi |
| 1349 // conversion after allocation but before the new object fields are set. |
| 1350 capacity = Add<HForceRepresentation>(capacity, Representation::Smi()); |
1340 HValue* new_elements = BuildAllocateElements(context, kind, capacity); | 1351 HValue* new_elements = BuildAllocateElements(context, kind, capacity); |
1341 BuildInitializeElementsHeader(new_elements, kind, capacity); | 1352 BuildInitializeElementsHeader(new_elements, kind, capacity); |
1342 return new_elements; | 1353 return new_elements; |
1343 } | 1354 } |
1344 | 1355 |
1345 | 1356 |
1346 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, | 1357 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array, |
1347 HValue* array_map, | 1358 HValue* array_map, |
1348 AllocationSiteMode mode, | 1359 AllocationSiteMode mode, |
1349 ElementsKind elements_kind, | 1360 ElementsKind elements_kind, |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1467 return AddLoad(object, HObjectAccess::ForFixedArrayLength()); | 1478 return AddLoad(object, HObjectAccess::ForFixedArrayLength()); |
1468 } | 1479 } |
1469 | 1480 |
1470 | 1481 |
1471 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, | 1482 HValue* HGraphBuilder::BuildNewElementsCapacity(HValue* context, |
1472 HValue* old_capacity) { | 1483 HValue* old_capacity) { |
1473 Zone* zone = this->zone(); | 1484 Zone* zone = this->zone(); |
1474 HValue* half_old_capacity = | 1485 HValue* half_old_capacity = |
1475 AddInstruction(HShr::New(zone, context, old_capacity, | 1486 AddInstruction(HShr::New(zone, context, old_capacity, |
1476 graph_->GetConstant1())); | 1487 graph_->GetConstant1())); |
1477 half_old_capacity->ClearFlag(HValue::kCanOverflow); | |
1478 | 1488 |
1479 HValue* new_capacity = AddInstruction( | 1489 HValue* new_capacity = AddInstruction( |
1480 HAdd::New(zone, context, half_old_capacity, old_capacity)); | 1490 HAdd::New(zone, context, half_old_capacity, old_capacity)); |
1481 new_capacity->ClearFlag(HValue::kCanOverflow); | 1491 new_capacity->ClearFlag(HValue::kCanOverflow); |
1482 | 1492 |
1483 HValue* min_growth = Add<HConstant>(16); | 1493 HValue* min_growth = Add<HConstant>(16); |
1484 | 1494 |
1485 new_capacity = AddInstruction( | 1495 new_capacity = AddInstruction( |
1486 HAdd::New(zone, context, new_capacity, min_growth)); | 1496 HAdd::New(zone, context, new_capacity, min_growth)); |
1487 new_capacity->ClearFlag(HValue::kCanOverflow); | 1497 new_capacity->ClearFlag(HValue::kCanOverflow); |
1488 | 1498 |
1489 return new_capacity; | 1499 return new_capacity; |
1490 } | 1500 } |
1491 | 1501 |
1492 | 1502 |
1493 void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) { | 1503 void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) { |
1494 Heap* heap = isolate()->heap(); | 1504 Heap* heap = isolate()->heap(); |
1495 int element_size = IsFastDoubleElementsKind(kind) ? kDoubleSize | 1505 int element_size = IsFastDoubleElementsKind(kind) ? kDoubleSize |
1496 : kPointerSize; | 1506 : kPointerSize; |
1497 int max_size = heap->MaxRegularSpaceAllocationSize() / element_size; | 1507 int max_size = heap->MaxRegularSpaceAllocationSize() / element_size; |
1498 max_size -= JSArray::kSize / element_size; | 1508 max_size -= JSArray::kSize / element_size; |
1499 HConstant* max_size_constant = Add<HConstant>(max_size); | 1509 HConstant* max_size_constant = Add<HConstant>(max_size); |
1500 // Since we're forcing Integer32 representation for this HBoundsCheck, | |
1501 // there's no need to Smi-check the index. | |
1502 Add<HBoundsCheck>(length, max_size_constant); | 1510 Add<HBoundsCheck>(length, max_size_constant); |
1503 } | 1511 } |
1504 | 1512 |
1505 | 1513 |
1506 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, | 1514 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, |
1507 HValue* elements, | 1515 HValue* elements, |
1508 ElementsKind kind, | 1516 ElementsKind kind, |
1509 ElementsKind new_kind, | 1517 ElementsKind new_kind, |
1510 HValue* length, | 1518 HValue* length, |
1511 HValue* new_capacity) { | 1519 HValue* new_capacity) { |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1920 return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole); | 1928 return AllocateArray(size_in_bytes, capacity, length_field, fill_with_hole); |
1921 } | 1929 } |
1922 | 1930 |
1923 | 1931 |
1924 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, | 1932 HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes, |
1925 HValue* capacity, | 1933 HValue* capacity, |
1926 HValue* length_field, | 1934 HValue* length_field, |
1927 bool fill_with_hole) { | 1935 bool fill_with_hole) { |
1928 HValue* context = builder()->environment()->LookupContext(); | 1936 HValue* context = builder()->environment()->LookupContext(); |
1929 | 1937 |
| 1938 // These HForceRepresentations are because we store these as fields in the |
| 1939 // objects we construct, and an int32-to-smi HChange could deopt. Accept |
| 1940 // the deopt possibility now, before allocation occurs. |
| 1941 capacity = builder()->Add<HForceRepresentation>(capacity, |
| 1942 Representation::Smi()); |
| 1943 length_field = builder()->Add<HForceRepresentation>(length_field, |
| 1944 Representation::Smi()); |
| 1945 |
1930 // Allocate (dealing with failure appropriately) | 1946 // Allocate (dealing with failure appropriately) |
1931 HAllocate::Flags flags = HAllocate::DefaultFlags(kind_); | 1947 HAllocate::Flags flags = HAllocate::DefaultFlags(kind_); |
1932 HAllocate* new_object = builder()->Add<HAllocate>(context, size_in_bytes, | 1948 HAllocate* new_object = builder()->Add<HAllocate>(context, size_in_bytes, |
1933 HType::JSArray(), flags); | 1949 HType::JSArray(), flags); |
1934 | 1950 |
1935 // Fill in the fields: map, properties, length | 1951 // Fill in the fields: map, properties, length |
1936 HValue* map; | 1952 HValue* map; |
1937 if (allocation_site_payload_ == NULL) { | 1953 if (allocation_site_payload_ == NULL) { |
1938 map = EmitInternalMapCode(); | 1954 map = EmitInternalMapCode(); |
1939 } else { | 1955 } else { |
(...skipping 7972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9912 if (ShouldProduceTraceOutput()) { | 9928 if (ShouldProduceTraceOutput()) { |
9913 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9929 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9914 } | 9930 } |
9915 | 9931 |
9916 #ifdef DEBUG | 9932 #ifdef DEBUG |
9917 graph_->Verify(false); // No full verify. | 9933 graph_->Verify(false); // No full verify. |
9918 #endif | 9934 #endif |
9919 } | 9935 } |
9920 | 9936 |
9921 } } // namespace v8::internal | 9937 } } // namespace v8::internal |
OLD | NEW |