OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 block->dominator()); | 586 block->dominator()); |
587 ASSERT(!dominator_analyzer.reachable()->Contains(block->block_id())); | 587 ASSERT(!dominator_analyzer.reachable()->Contains(block->block_id())); |
588 } | 588 } |
589 } | 589 } |
590 } | 590 } |
591 } | 591 } |
592 | 592 |
593 #endif | 593 #endif |
594 | 594 |
595 | 595 |
596 HConstant* HGraph::GetConstantInt32(SetOncePointer<HConstant>* pointer, | 596 HConstant* HGraph::GetConstant(SetOncePointer<HConstant>* pointer, |
597 int32_t value) { | 597 int32_t value) { |
598 if (!pointer->is_set()) { | 598 if (!pointer->is_set()) { |
599 HConstant* constant = | 599 HConstant* constant = new(zone()) HConstant(value); |
600 new(zone()) HConstant(value, Representation::Integer32()); | |
601 constant->InsertAfter(GetConstantUndefined()); | 600 constant->InsertAfter(GetConstantUndefined()); |
602 pointer->set(constant); | 601 pointer->set(constant); |
603 } | 602 } |
604 return pointer->get(); | 603 return pointer->get(); |
605 } | 604 } |
606 | 605 |
607 | 606 |
608 HConstant* HGraph::GetConstant0() { | 607 HConstant* HGraph::GetConstant0() { |
609 return GetConstantInt32(&constant_0_, 0); | 608 return GetConstant(&constant_0_, 0); |
610 } | 609 } |
611 | 610 |
612 | 611 |
613 HConstant* HGraph::GetConstant1() { | 612 HConstant* HGraph::GetConstant1() { |
614 return GetConstantInt32(&constant_1_, 1); | 613 return GetConstant(&constant_1_, 1); |
615 } | 614 } |
616 | 615 |
617 | 616 |
618 HConstant* HGraph::GetConstantMinus1() { | 617 HConstant* HGraph::GetConstantMinus1() { |
619 return GetConstantInt32(&constant_minus1_, -1); | 618 return GetConstant(&constant_minus1_, -1); |
620 } | 619 } |
621 | 620 |
622 | 621 |
623 #define DEFINE_GET_CONSTANT(Name, name, htype, boolean_value) \ | 622 #define DEFINE_GET_CONSTANT(Name, name, htype, boolean_value) \ |
624 HConstant* HGraph::GetConstant##Name() { \ | 623 HConstant* HGraph::GetConstant##Name() { \ |
625 if (!constant_##name##_.is_set()) { \ | 624 if (!constant_##name##_.is_set()) { \ |
626 HConstant* constant = new(zone()) HConstant( \ | 625 HConstant* constant = new(zone()) HConstant( \ |
627 isolate()->factory()->name##_value(), \ | 626 isolate()->factory()->name##_value(), \ |
628 UniqueValueId(isolate()->heap()->name##_value()), \ | 627 UniqueValueId(isolate()->heap()->name##_value()), \ |
629 Representation::Tagged(), \ | 628 Representation::Tagged(), \ |
(...skipping 11 matching lines...) Expand all Loading... |
641 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true) | 640 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true) |
642 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false) | 641 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false) |
643 DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false) | 642 DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false) |
644 DEFINE_GET_CONSTANT(Null, null, HType::Tagged(), false) | 643 DEFINE_GET_CONSTANT(Null, null, HType::Tagged(), false) |
645 | 644 |
646 | 645 |
647 #undef DEFINE_GET_CONSTANT | 646 #undef DEFINE_GET_CONSTANT |
648 | 647 |
649 | 648 |
650 HConstant* HGraph::GetInvalidContext() { | 649 HConstant* HGraph::GetInvalidContext() { |
651 return GetConstantInt32(&constant_invalid_context_, 0xFFFFC0C7); | 650 return GetConstant(&constant_invalid_context_, 0xFFFFC0C7); |
652 } | 651 } |
653 | 652 |
654 | 653 |
655 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position) | 654 HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position) |
656 : builder_(builder), | 655 : builder_(builder), |
657 position_(position), | 656 position_(position), |
658 finished_(false), | 657 finished_(false), |
659 did_then_(false), | 658 did_then_(false), |
660 did_else_(false), | 659 did_else_(false), |
661 did_and_(false), | 660 did_and_(false), |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 | 971 |
973 | 972 |
974 void HGraphBuilder::AddSimulate(BailoutId id, | 973 void HGraphBuilder::AddSimulate(BailoutId id, |
975 RemovableSimulate removable) { | 974 RemovableSimulate removable) { |
976 ASSERT(current_block() != NULL); | 975 ASSERT(current_block() != NULL); |
977 ASSERT(no_side_effects_scope_count_ == 0); | 976 ASSERT(no_side_effects_scope_count_ == 0); |
978 current_block()->AddSimulate(id, removable); | 977 current_block()->AddSimulate(id, removable); |
979 } | 978 } |
980 | 979 |
981 | 980 |
982 HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, | 981 HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, HValue* length) { |
983 HValue* length, | 982 HBoundsCheck* result = new(graph()->zone()) HBoundsCheck(index, length); |
984 BoundsCheckKeyMode key_mode) { | |
985 HBoundsCheck* result = new(graph()->zone()) HBoundsCheck( | |
986 index, length, key_mode); | |
987 AddInstruction(result); | 983 AddInstruction(result); |
988 return result; | 984 return result; |
989 } | 985 } |
990 | 986 |
991 | 987 |
992 HReturn* HGraphBuilder::AddReturn(HValue* value) { | 988 HReturn* HGraphBuilder::AddReturn(HValue* value) { |
993 HValue* context = environment()->LookupContext(); | 989 HValue* context = environment()->LookupContext(); |
994 int num_parameters = graph()->info()->num_parameters(); | 990 int num_parameters = graph()->info()->num_parameters(); |
995 HValue* params = AddInstruction(new(graph()->zone()) | 991 HValue* params = AddInstruction(new(graph()->zone()) |
996 HConstant(num_parameters, Representation::Integer32())); | 992 HConstant(num_parameters, Representation::Integer32())); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 new_length->ClearFlag(HValue::kCanOverflow); | 1158 new_length->ClearFlag(HValue::kCanOverflow); |
1163 | 1159 |
1164 Representation representation = IsFastElementsKind(kind) | 1160 Representation representation = IsFastElementsKind(kind) |
1165 ? Representation::Smi() : Representation::Tagged(); | 1161 ? Representation::Smi() : Representation::Tagged(); |
1166 AddStore(object, HObjectAccess::ForArrayLength(), new_length, | 1162 AddStore(object, HObjectAccess::ForArrayLength(), new_length, |
1167 representation); | 1163 representation); |
1168 } | 1164 } |
1169 | 1165 |
1170 length_checker.Else(); | 1166 length_checker.Else(); |
1171 | 1167 |
1172 AddBoundsCheck(key, length, ALLOW_SMI_KEY); | 1168 AddBoundsCheck(key, length); |
1173 environment()->Push(elements); | 1169 environment()->Push(elements); |
1174 | 1170 |
1175 length_checker.End(); | 1171 length_checker.End(); |
1176 | 1172 |
1177 return environment()->Pop(); | 1173 return environment()->Pop(); |
1178 } | 1174 } |
1179 | 1175 |
1180 | 1176 |
1181 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, | 1177 HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object, |
1182 HValue* elements, | 1178 HValue* elements, |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1267 negative_checker.Then(); | 1263 negative_checker.Then(); |
1268 HInstruction* result = BuildExternalArrayElementAccess( | 1264 HInstruction* result = BuildExternalArrayElementAccess( |
1269 external_elements, key, val, bounds_check, | 1265 external_elements, key, val, bounds_check, |
1270 elements_kind, is_store); | 1266 elements_kind, is_store); |
1271 AddInstruction(result); | 1267 AddInstruction(result); |
1272 negative_checker.ElseDeopt(); | 1268 negative_checker.ElseDeopt(); |
1273 length_checker.End(); | 1269 length_checker.End(); |
1274 return result; | 1270 return result; |
1275 } else { | 1271 } else { |
1276 ASSERT(store_mode == STANDARD_STORE); | 1272 ASSERT(store_mode == STANDARD_STORE); |
1277 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY); | 1273 checked_key = AddBoundsCheck(key, length); |
1278 HLoadExternalArrayPointer* external_elements = | 1274 HLoadExternalArrayPointer* external_elements = |
1279 new(zone) HLoadExternalArrayPointer(elements); | 1275 new(zone) HLoadExternalArrayPointer(elements); |
1280 AddInstruction(external_elements); | 1276 AddInstruction(external_elements); |
1281 return AddInstruction(BuildExternalArrayElementAccess( | 1277 return AddInstruction(BuildExternalArrayElementAccess( |
1282 external_elements, checked_key, val, mapcheck, | 1278 external_elements, checked_key, val, mapcheck, |
1283 elements_kind, is_store)); | 1279 elements_kind, is_store)); |
1284 } | 1280 } |
1285 } | 1281 } |
1286 ASSERT(fast_smi_only_elements || | 1282 ASSERT(fast_smi_only_elements || |
1287 fast_elements || | 1283 fast_elements || |
1288 IsFastDoubleElementsKind(elements_kind)); | 1284 IsFastDoubleElementsKind(elements_kind)); |
1289 | 1285 |
1290 // In case val is stored into a fast smi array, assure that the value is a smi | 1286 // In case val is stored into a fast smi array, assure that the value is a smi |
1291 // before manipulating the backing store. Otherwise the actual store may | 1287 // before manipulating the backing store. Otherwise the actual store may |
1292 // deopt, leaving the backing store in an invalid state. | 1288 // deopt, leaving the backing store in an invalid state. |
1293 if (is_store && IsFastSmiElementsKind(elements_kind) && | 1289 if (is_store && IsFastSmiElementsKind(elements_kind) && |
1294 !val->type().IsSmi()) { | 1290 !val->type().IsSmi()) { |
1295 val = AddInstruction(new(zone) HForceRepresentation( | 1291 val = AddInstruction(new(zone) HForceRepresentation( |
1296 val, Representation::Smi())); | 1292 val, Representation::Smi())); |
1297 } | 1293 } |
1298 | 1294 |
1299 if (IsGrowStoreMode(store_mode)) { | 1295 if (IsGrowStoreMode(store_mode)) { |
1300 NoObservableSideEffectsScope no_effects(this); | 1296 NoObservableSideEffectsScope no_effects(this); |
1301 elements = BuildCheckForCapacityGrow(object, elements, elements_kind, | 1297 elements = BuildCheckForCapacityGrow(object, elements, elements_kind, |
1302 length, key, is_js_array); | 1298 length, key, is_js_array); |
1303 checked_key = key; | 1299 checked_key = key; |
1304 } else { | 1300 } else { |
1305 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY); | 1301 checked_key = AddBoundsCheck(key, length); |
1306 | 1302 |
1307 if (is_store && (fast_elements || fast_smi_only_elements)) { | 1303 if (is_store && (fast_elements || fast_smi_only_elements)) { |
1308 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { | 1304 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { |
1309 NoObservableSideEffectsScope no_effects(this); | 1305 NoObservableSideEffectsScope no_effects(this); |
1310 | 1306 |
1311 elements = BuildCopyElementsOnWrite(object, elements, elements_kind, | 1307 elements = BuildCopyElementsOnWrite(object, elements, elements_kind, |
1312 length); | 1308 length); |
1313 } else { | 1309 } else { |
1314 HCheckMaps* check_cow_map = HCheckMaps::New( | 1310 HCheckMaps* check_cow_map = HCheckMaps::New( |
1315 elements, isolate()->factory()->fixed_array_map(), zone); | 1311 elements, isolate()->factory()->fixed_array_map(), zone); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1463 } | 1459 } |
1464 | 1460 |
1465 | 1461 |
1466 void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) { | 1462 void HGraphBuilder::BuildNewSpaceArrayCheck(HValue* length, ElementsKind kind) { |
1467 Zone* zone = this->zone(); | 1463 Zone* zone = this->zone(); |
1468 Heap* heap = isolate()->heap(); | 1464 Heap* heap = isolate()->heap(); |
1469 int element_size = IsFastDoubleElementsKind(kind) ? kDoubleSize | 1465 int element_size = IsFastDoubleElementsKind(kind) ? kDoubleSize |
1470 : kPointerSize; | 1466 : kPointerSize; |
1471 int max_size = heap->MaxRegularSpaceAllocationSize() / element_size; | 1467 int max_size = heap->MaxRegularSpaceAllocationSize() / element_size; |
1472 max_size -= JSArray::kSize / element_size; | 1468 max_size -= JSArray::kSize / element_size; |
1473 HConstant* max_size_constant = | 1469 HConstant* max_size_constant = new(zone) HConstant(max_size); |
1474 new(zone) HConstant(max_size, Representation::Integer32()); | |
1475 AddInstruction(max_size_constant); | 1470 AddInstruction(max_size_constant); |
1476 // Since we're forcing Integer32 representation for this HBoundsCheck, | 1471 // Since we're forcing Integer32 representation for this HBoundsCheck, |
1477 // there's no need to Smi-check the index. | 1472 // there's no need to Smi-check the index. |
1478 AddInstruction(new(zone) HBoundsCheck( | 1473 AddInstruction(new(zone) HBoundsCheck(length, max_size_constant)); |
1479 length, max_size_constant, DONT_ALLOW_SMI_KEY)); | |
1480 } | 1474 } |
1481 | 1475 |
1482 | 1476 |
1483 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, | 1477 HValue* HGraphBuilder::BuildGrowElementsCapacity(HValue* object, |
1484 HValue* elements, | 1478 HValue* elements, |
1485 ElementsKind kind, | 1479 ElementsKind kind, |
1486 HValue* length, | 1480 HValue* length, |
1487 HValue* new_capacity) { | 1481 HValue* new_capacity) { |
1488 HValue* context = environment()->LookupContext(); | 1482 HValue* context = environment()->LookupContext(); |
1489 | 1483 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1537 } | 1531 } |
1538 | 1532 |
1539 // Since we're about to store a hole value, the store instruction below must | 1533 // Since we're about to store a hole value, the store instruction below must |
1540 // assume an elements kind that supports heap object values. | 1534 // assume an elements kind that supports heap object values. |
1541 if (IsFastSmiOrObjectElementsKind(elements_kind)) { | 1535 if (IsFastSmiOrObjectElementsKind(elements_kind)) { |
1542 elements_kind = FAST_HOLEY_ELEMENTS; | 1536 elements_kind = FAST_HOLEY_ELEMENTS; |
1543 } | 1537 } |
1544 | 1538 |
1545 if (unfold_loop) { | 1539 if (unfold_loop) { |
1546 for (int i = 0; i < initial_capacity; i++) { | 1540 for (int i = 0; i < initial_capacity; i++) { |
1547 HInstruction* key = AddInstruction(new(zone) | 1541 HInstruction* key = AddInstruction(new(zone) HConstant(i)); |
1548 HConstant(i, Representation::Integer32())); | |
1549 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); | 1542 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); |
1550 } | 1543 } |
1551 } else { | 1544 } else { |
1552 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); | 1545 LoopBuilder builder(this, context, LoopBuilder::kPostIncrement); |
1553 | 1546 |
1554 HValue* key = builder.BeginBody(from, to, Token::LT); | 1547 HValue* key = builder.BeginBody(from, to, Token::LT); |
1555 | 1548 |
1556 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); | 1549 AddInstruction(new(zone) HStoreKeyed(elements, key, hole, elements_kind)); |
1557 | 1550 |
1558 builder.EndBody(); | 1551 builder.EndBody(); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1661 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { | 1654 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { |
1662 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); | 1655 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); |
1663 AddStore(object_elements, access, AddLoad(boilerplate_elements, access)); | 1656 AddStore(object_elements, access, AddLoad(boilerplate_elements, access)); |
1664 } | 1657 } |
1665 | 1658 |
1666 // Copy the elements array contents. | 1659 // Copy the elements array contents. |
1667 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold | 1660 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold |
1668 // copying loops with constant length up to a given boundary and use this | 1661 // copying loops with constant length up to a given boundary and use this |
1669 // helper here instead. | 1662 // helper here instead. |
1670 for (int i = 0; i < length; i++) { | 1663 for (int i = 0; i < length; i++) { |
1671 HValue* key_constant = | 1664 HValue* key_constant = AddInstruction(new(zone) HConstant(i)); |
1672 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); | |
1673 HInstruction* value = | 1665 HInstruction* value = |
1674 AddInstruction(new(zone) HLoadKeyed(boilerplate_elements, | 1666 AddInstruction(new(zone) HLoadKeyed(boilerplate_elements, |
1675 key_constant, | 1667 key_constant, |
1676 NULL, | 1668 NULL, |
1677 kind)); | 1669 kind)); |
1678 AddInstruction(new(zone) HStoreKeyed(object_elements, | 1670 AddInstruction(new(zone) HStoreKeyed(object_elements, |
1679 key_constant, | 1671 key_constant, |
1680 value, | 1672 value, |
1681 kind)); | 1673 kind)); |
1682 } | 1674 } |
(...skipping 3657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5340 AddSimulate(stmt->PrepareId()); | 5332 AddSimulate(stmt->PrepareId()); |
5341 | 5333 |
5342 HInstruction* array = AddInstruction( | 5334 HInstruction* array = AddInstruction( |
5343 new(zone()) HForInCacheArray( | 5335 new(zone()) HForInCacheArray( |
5344 enumerable, | 5336 enumerable, |
5345 map, | 5337 map, |
5346 DescriptorArray::kEnumCacheBridgeCacheIndex)); | 5338 DescriptorArray::kEnumCacheBridgeCacheIndex)); |
5347 | 5339 |
5348 HInstruction* enum_length = AddInstruction(new(zone()) HMapEnumLength(map)); | 5340 HInstruction* enum_length = AddInstruction(new(zone()) HMapEnumLength(map)); |
5349 | 5341 |
5350 HInstruction* start_index = AddInstruction(new(zone()) HConstant( | 5342 HInstruction* start_index = AddInstruction(new(zone()) HConstant(0)); |
5351 Handle<Object>(Smi::FromInt(0), isolate()), Representation::Integer32())); | |
5352 | 5343 |
5353 Push(map); | 5344 Push(map); |
5354 Push(array); | 5345 Push(array); |
5355 Push(enum_length); | 5346 Push(enum_length); |
5356 Push(start_index); | 5347 Push(start_index); |
5357 | 5348 |
5358 HInstruction* index_cache = AddInstruction( | 5349 HInstruction* index_cache = AddInstruction( |
5359 new(zone()) HForInCacheArray( | 5350 new(zone()) HForInCacheArray( |
5360 enumerable, | 5351 enumerable, |
5361 map, | 5352 map, |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6078 // If the subexpression is a literal or a simple materialized literal it | 6069 // If the subexpression is a literal or a simple materialized literal it |
6079 // is already set in the cloned array. | 6070 // is already set in the cloned array. |
6080 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 6071 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
6081 | 6072 |
6082 CHECK_ALIVE(VisitForValue(subexpr)); | 6073 CHECK_ALIVE(VisitForValue(subexpr)); |
6083 HValue* value = Pop(); | 6074 HValue* value = Pop(); |
6084 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); | 6075 if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal"); |
6085 | 6076 |
6086 elements = AddLoadElements(literal); | 6077 elements = AddLoadElements(literal); |
6087 | 6078 |
6088 HValue* key = AddInstruction( | 6079 HValue* key = AddInstruction(new(zone()) HConstant(i)); |
6089 new(zone()) HConstant(Handle<Object>(Smi::FromInt(i), isolate()), | |
6090 Representation::Integer32())); | |
6091 | 6080 |
6092 switch (boilerplate_elements_kind) { | 6081 switch (boilerplate_elements_kind) { |
6093 case FAST_SMI_ELEMENTS: | 6082 case FAST_SMI_ELEMENTS: |
6094 case FAST_HOLEY_SMI_ELEMENTS: | 6083 case FAST_HOLEY_SMI_ELEMENTS: |
6095 case FAST_ELEMENTS: | 6084 case FAST_ELEMENTS: |
6096 case FAST_HOLEY_ELEMENTS: | 6085 case FAST_HOLEY_ELEMENTS: |
6097 case FAST_DOUBLE_ELEMENTS: | 6086 case FAST_DOUBLE_ELEMENTS: |
6098 case FAST_HOLEY_DOUBLE_ELEMENTS: | 6087 case FAST_HOLEY_DOUBLE_ELEMENTS: |
6099 AddInstruction(new(zone()) HStoreKeyed( | 6088 AddInstruction(new(zone()) HStoreKeyed( |
6100 elements, | 6089 elements, |
(...skipping 1174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7275 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); | 7264 new(zone()) HHasInstanceTypeAndBranch(object, JS_ARRAY_TYPE); |
7276 typecheck->SetSuccessorAt(0, if_jsarray); | 7265 typecheck->SetSuccessorAt(0, if_jsarray); |
7277 typecheck->SetSuccessorAt(1, if_fastobject); | 7266 typecheck->SetSuccessorAt(1, if_fastobject); |
7278 current_block()->Finish(typecheck); | 7267 current_block()->Finish(typecheck); |
7279 | 7268 |
7280 set_current_block(if_jsarray); | 7269 set_current_block(if_jsarray); |
7281 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(), | 7270 HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(), |
7282 typecheck, Representation::Smi()); | 7271 typecheck, Representation::Smi()); |
7283 length->set_type(HType::Smi()); | 7272 length->set_type(HType::Smi()); |
7284 | 7273 |
7285 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY); | 7274 checked_key = AddBoundsCheck(key, length); |
7286 access = AddInstruction(BuildFastElementAccess( | 7275 access = AddInstruction(BuildFastElementAccess( |
7287 elements, checked_key, val, elements_kind_branch, | 7276 elements, checked_key, val, elements_kind_branch, |
7288 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); | 7277 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); |
7289 if (!is_store) { | 7278 if (!is_store) { |
7290 Push(access); | 7279 Push(access); |
7291 } | 7280 } |
7292 | 7281 |
7293 *has_side_effects |= access->HasObservableSideEffects(); | 7282 *has_side_effects |= access->HasObservableSideEffects(); |
7294 // The caller will use has_side_effects and add correct Simulate. | 7283 // The caller will use has_side_effects and add correct Simulate. |
7295 access->SetFlag(HValue::kHasNoObservableSideEffects); | 7284 access->SetFlag(HValue::kHasNoObservableSideEffects); |
7296 if (position != -1) { | 7285 if (position != -1) { |
7297 access->set_position(position); | 7286 access->set_position(position); |
7298 } | 7287 } |
7299 if_jsarray->GotoNoSimulate(join); | 7288 if_jsarray->GotoNoSimulate(join); |
7300 | 7289 |
7301 set_current_block(if_fastobject); | 7290 set_current_block(if_fastobject); |
7302 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 7291 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
7303 checked_key = AddBoundsCheck(key, length, ALLOW_SMI_KEY); | 7292 checked_key = AddBoundsCheck(key, length); |
7304 access = AddInstruction(BuildFastElementAccess( | 7293 access = AddInstruction(BuildFastElementAccess( |
7305 elements, checked_key, val, elements_kind_branch, | 7294 elements, checked_key, val, elements_kind_branch, |
7306 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); | 7295 elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); |
7307 } else if (elements_kind == DICTIONARY_ELEMENTS) { | 7296 } else if (elements_kind == DICTIONARY_ELEMENTS) { |
7308 if (is_store) { | 7297 if (is_store) { |
7309 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); | 7298 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); |
7310 } else { | 7299 } else { |
7311 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); | 7300 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); |
7312 } | 7301 } |
7313 } else { // External array elements. | 7302 } else { // External array elements. |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7431 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("length"))) return false; | 7420 if (!name->IsOneByteEqualTo(STATIC_ASCII_VECTOR("length"))) return false; |
7432 | 7421 |
7433 if (function_state()->outer() == NULL) { | 7422 if (function_state()->outer() == NULL) { |
7434 HInstruction* elements = AddInstruction( | 7423 HInstruction* elements = AddInstruction( |
7435 new(zone()) HArgumentsElements(false)); | 7424 new(zone()) HArgumentsElements(false)); |
7436 result = new(zone()) HArgumentsLength(elements); | 7425 result = new(zone()) HArgumentsLength(elements); |
7437 } else { | 7426 } else { |
7438 // Number of arguments without receiver. | 7427 // Number of arguments without receiver. |
7439 int argument_count = environment()-> | 7428 int argument_count = environment()-> |
7440 arguments_environment()->parameter_count() - 1; | 7429 arguments_environment()->parameter_count() - 1; |
7441 result = new(zone()) HConstant( | 7430 result = new(zone()) HConstant(argument_count); |
7442 Handle<Object>(Smi::FromInt(argument_count), isolate()), | |
7443 Representation::Integer32()); | |
7444 } | 7431 } |
7445 } else { | 7432 } else { |
7446 Push(graph()->GetArgumentsObject()); | 7433 Push(graph()->GetArgumentsObject()); |
7447 VisitForValue(expr->key()); | 7434 VisitForValue(expr->key()); |
7448 if (HasStackOverflow() || current_block() == NULL) return true; | 7435 if (HasStackOverflow() || current_block() == NULL) return true; |
7449 HValue* key = Pop(); | 7436 HValue* key = Pop(); |
7450 Drop(1); // Arguments object. | 7437 Drop(1); // Arguments object. |
7451 if (function_state()->outer() == NULL) { | 7438 if (function_state()->outer() == NULL) { |
7452 HInstruction* elements = AddInstruction( | 7439 HInstruction* elements = AddInstruction( |
7453 new(zone()) HArgumentsElements(false)); | 7440 new(zone()) HArgumentsElements(false)); |
7454 HInstruction* length = AddInstruction( | 7441 HInstruction* length = AddInstruction( |
7455 new(zone()) HArgumentsLength(elements)); | 7442 new(zone()) HArgumentsLength(elements)); |
7456 HInstruction* checked_key = AddBoundsCheck(key, length); | 7443 HInstruction* checked_key = AddBoundsCheck(key, length); |
7457 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 7444 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
7458 } else { | 7445 } else { |
7459 EnsureArgumentsArePushedForAccess(); | 7446 EnsureArgumentsArePushedForAccess(); |
7460 | 7447 |
7461 // Number of arguments without receiver. | 7448 // Number of arguments without receiver. |
7462 HInstruction* elements = function_state()->arguments_elements(); | 7449 HInstruction* elements = function_state()->arguments_elements(); |
7463 int argument_count = environment()-> | 7450 int argument_count = environment()-> |
7464 arguments_environment()->parameter_count() - 1; | 7451 arguments_environment()->parameter_count() - 1; |
7465 HInstruction* length = AddInstruction(new(zone()) HConstant( | 7452 HInstruction* length = AddInstruction(new(zone()) HConstant( |
7466 Handle<Object>(Smi::FromInt(argument_count), isolate()), | 7453 argument_count)); |
7467 Representation::Integer32())); | |
7468 HInstruction* checked_key = AddBoundsCheck(key, length); | 7454 HInstruction* checked_key = AddBoundsCheck(key, length); |
7469 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 7455 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
7470 } | 7456 } |
7471 } | 7457 } |
7472 ast_context()->ReturnInstruction(result, expr->id()); | 7458 ast_context()->ReturnInstruction(result, expr->id()); |
7473 return true; | 7459 return true; |
7474 } | 7460 } |
7475 | 7461 |
7476 | 7462 |
7477 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { | 7463 void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8327 Pop(); // Pop receiver. | 8313 Pop(); // Pop receiver. |
8328 HValue* context = environment()->LookupContext(); | 8314 HValue* context = environment()->LookupContext(); |
8329 HInstruction* result = NULL; | 8315 HInstruction* result = NULL; |
8330 // Use sqrt() if exponent is 0.5 or -0.5. | 8316 // Use sqrt() if exponent is 0.5 or -0.5. |
8331 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { | 8317 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { |
8332 double exponent = HConstant::cast(right)->DoubleValue(); | 8318 double exponent = HConstant::cast(right)->DoubleValue(); |
8333 if (exponent == 0.5) { | 8319 if (exponent == 0.5) { |
8334 result = | 8320 result = |
8335 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); | 8321 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); |
8336 } else if (exponent == -0.5) { | 8322 } else if (exponent == -0.5) { |
8337 HConstant* double_one = | 8323 HConstant* double_one = new(zone()) HConstant( |
8338 new(zone()) HConstant(Handle<Object>(Smi::FromInt(1), | 8324 1, Representation::Double()); |
8339 isolate()), | |
8340 Representation::Double()); | |
8341 AddInstruction(double_one); | 8325 AddInstruction(double_one); |
8342 HInstruction* sqrt = | 8326 HInstruction* sqrt = |
8343 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); | 8327 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); |
8344 AddInstruction(sqrt); | 8328 AddInstruction(sqrt); |
8345 // MathPowHalf doesn't have side effects so there's no need for | 8329 // MathPowHalf doesn't have side effects so there's no need for |
8346 // an environment simulation here. | 8330 // an environment simulation here. |
8347 ASSERT(!sqrt->HasObservableSideEffects()); | 8331 ASSERT(!sqrt->HasObservableSideEffects()); |
8348 result = HDiv::New(zone(), context, double_one, sqrt); | 8332 result = HDiv::New(zone(), context, double_one, sqrt); |
8349 } else if (exponent == 2.0) { | 8333 } else if (exponent == 2.0) { |
8350 result = HMul::New(zone(), context, left, left); | 8334 result = HMul::New(zone(), context, left, left); |
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9284 HValue* index) { | 9268 HValue* index) { |
9285 if (string->IsConstant() && index->IsConstant()) { | 9269 if (string->IsConstant() && index->IsConstant()) { |
9286 HConstant* c_string = HConstant::cast(string); | 9270 HConstant* c_string = HConstant::cast(string); |
9287 HConstant* c_index = HConstant::cast(index); | 9271 HConstant* c_index = HConstant::cast(index); |
9288 if (c_string->HasStringValue() && c_index->HasNumberValue()) { | 9272 if (c_string->HasStringValue() && c_index->HasNumberValue()) { |
9289 int32_t i = c_index->NumberValueAsInteger32(); | 9273 int32_t i = c_index->NumberValueAsInteger32(); |
9290 Handle<String> s = c_string->StringValue(); | 9274 Handle<String> s = c_string->StringValue(); |
9291 if (i < 0 || i >= s->length()) { | 9275 if (i < 0 || i >= s->length()) { |
9292 return new(zone()) HConstant(OS::nan_value(), Representation::Double()); | 9276 return new(zone()) HConstant(OS::nan_value(), Representation::Double()); |
9293 } | 9277 } |
9294 return new(zone()) HConstant(s->Get(i), Representation::Integer32()); | 9278 return new(zone()) HConstant(s->Get(i)); |
9295 } | 9279 } |
9296 } | 9280 } |
9297 BuildCheckNonSmi(string); | 9281 BuildCheckNonSmi(string); |
9298 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); | 9282 AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
9299 HInstruction* length = HStringLength::New(zone(), string); | 9283 HInstruction* length = HStringLength::New(zone(), string); |
9300 AddInstruction(length); | 9284 AddInstruction(length); |
9301 HInstruction* checked_index = AddBoundsCheck(index, length); | 9285 HInstruction* checked_index = AddBoundsCheck(index, length); |
9302 return new(zone()) HStringCharCodeAt(context, string, checked_index); | 9286 return new(zone()) HStringCharCodeAt(context, string, checked_index); |
9303 } | 9287 } |
9304 | 9288 |
(...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10086 Handle<FixedArrayBase> elements, | 10070 Handle<FixedArrayBase> elements, |
10087 Handle<FixedArrayBase> original_elements, | 10071 Handle<FixedArrayBase> original_elements, |
10088 ElementsKind kind, | 10072 ElementsKind kind, |
10089 HValue* object_elements, | 10073 HValue* object_elements, |
10090 HInstruction* target, | 10074 HInstruction* target, |
10091 int* offset) { | 10075 int* offset) { |
10092 Zone* zone = this->zone(); | 10076 Zone* zone = this->zone(); |
10093 | 10077 |
10094 int elements_length = elements->length(); | 10078 int elements_length = elements->length(); |
10095 HValue* object_elements_length = | 10079 HValue* object_elements_length = |
10096 AddInstruction(new(zone) HConstant( | 10080 AddInstruction(new(zone) HConstant(elements_length)); |
10097 elements_length, Representation::Integer32())); | |
10098 | 10081 |
10099 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); | 10082 BuildInitializeElementsHeader(object_elements, kind, object_elements_length); |
10100 | 10083 |
10101 // Copy elements backing store content. | 10084 // Copy elements backing store content. |
10102 if (elements->IsFixedDoubleArray()) { | 10085 if (elements->IsFixedDoubleArray()) { |
10103 BuildEmitFixedDoubleArray(elements, kind, object_elements); | 10086 BuildEmitFixedDoubleArray(elements, kind, object_elements); |
10104 } else if (elements->IsFixedArray()) { | 10087 } else if (elements->IsFixedArray()) { |
10105 BuildEmitFixedArray(elements, original_elements, kind, object_elements, | 10088 BuildEmitFixedArray(elements, original_elements, kind, object_elements, |
10106 target, offset); | 10089 target, offset); |
10107 } else { | 10090 } else { |
10108 UNREACHABLE(); | 10091 UNREACHABLE(); |
10109 } | 10092 } |
10110 } | 10093 } |
10111 | 10094 |
10112 | 10095 |
10113 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( | 10096 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( |
10114 Handle<FixedArrayBase> elements, | 10097 Handle<FixedArrayBase> elements, |
10115 ElementsKind kind, | 10098 ElementsKind kind, |
10116 HValue* object_elements) { | 10099 HValue* object_elements) { |
10117 Zone* zone = this->zone(); | 10100 Zone* zone = this->zone(); |
10118 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( | 10101 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( |
10119 elements, Representation::Tagged())); | 10102 elements, Representation::Tagged())); |
10120 int elements_length = elements->length(); | 10103 int elements_length = elements->length(); |
10121 for (int i = 0; i < elements_length; i++) { | 10104 for (int i = 0; i < elements_length; i++) { |
10122 HValue* key_constant = | 10105 HValue* key_constant = AddInstruction(new(zone) HConstant(i)); |
10123 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); | |
10124 HInstruction* value_instruction = | 10106 HInstruction* value_instruction = |
10125 AddInstruction(new(zone) HLoadKeyed( | 10107 AddInstruction(new(zone) HLoadKeyed( |
10126 boilerplate_elements, key_constant, NULL, kind, ALLOW_RETURN_HOLE)); | 10108 boilerplate_elements, key_constant, NULL, kind, ALLOW_RETURN_HOLE)); |
10127 HInstruction* store = AddInstruction(new(zone) HStoreKeyed( | 10109 HInstruction* store = AddInstruction(new(zone) HStoreKeyed( |
10128 object_elements, key_constant, value_instruction, kind)); | 10110 object_elements, key_constant, value_instruction, kind)); |
10129 store->ClearFlag(HValue::kDeoptimizeOnUndefined); | 10111 store->ClearFlag(HValue::kDeoptimizeOnUndefined); |
10130 } | 10112 } |
10131 } | 10113 } |
10132 | 10114 |
10133 | 10115 |
10134 void HOptimizedGraphBuilder::BuildEmitFixedArray( | 10116 void HOptimizedGraphBuilder::BuildEmitFixedArray( |
10135 Handle<FixedArrayBase> elements, | 10117 Handle<FixedArrayBase> elements, |
10136 Handle<FixedArrayBase> original_elements, | 10118 Handle<FixedArrayBase> original_elements, |
10137 ElementsKind kind, | 10119 ElementsKind kind, |
10138 HValue* object_elements, | 10120 HValue* object_elements, |
10139 HInstruction* target, | 10121 HInstruction* target, |
10140 int* offset) { | 10122 int* offset) { |
10141 Zone* zone = this->zone(); | 10123 Zone* zone = this->zone(); |
10142 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( | 10124 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( |
10143 elements, Representation::Tagged())); | 10125 elements, Representation::Tagged())); |
10144 int elements_length = elements->length(); | 10126 int elements_length = elements->length(); |
10145 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 10127 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
10146 Handle<FixedArray> original_fast_elements = | 10128 Handle<FixedArray> original_fast_elements = |
10147 Handle<FixedArray>::cast(original_elements); | 10129 Handle<FixedArray>::cast(original_elements); |
10148 for (int i = 0; i < elements_length; i++) { | 10130 for (int i = 0; i < elements_length; i++) { |
10149 Handle<Object> value(fast_elements->get(i), isolate()); | 10131 Handle<Object> value(fast_elements->get(i), isolate()); |
10150 HValue* key_constant = | 10132 HValue* key_constant = AddInstruction(new(zone) HConstant(i)); |
10151 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); | |
10152 if (value->IsJSObject()) { | 10133 if (value->IsJSObject()) { |
10153 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 10134 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
10154 Handle<JSObject> original_value_object = Handle<JSObject>::cast( | 10135 Handle<JSObject> original_value_object = Handle<JSObject>::cast( |
10155 Handle<Object>(original_fast_elements->get(i), isolate())); | 10136 Handle<Object>(original_fast_elements->get(i), isolate())); |
10156 HInstruction* value_instruction = | 10137 HInstruction* value_instruction = |
10157 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); | 10138 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); |
10158 AddInstruction(new(zone) HStoreKeyed( | 10139 AddInstruction(new(zone) HStoreKeyed( |
10159 object_elements, key_constant, value_instruction, kind)); | 10140 object_elements, key_constant, value_instruction, kind)); |
10160 BuildEmitDeepCopy(value_object, original_value_object, target, | 10141 BuildEmitDeepCopy(value_object, original_value_object, target, |
10161 offset, DONT_TRACK_ALLOCATION_SITE); | 10142 offset, DONT_TRACK_ALLOCATION_SITE); |
(...skipping 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11516 } | 11497 } |
11517 } | 11498 } |
11518 | 11499 |
11519 #ifdef DEBUG | 11500 #ifdef DEBUG |
11520 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11501 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
11521 if (allocator_ != NULL) allocator_->Verify(); | 11502 if (allocator_ != NULL) allocator_->Verify(); |
11522 #endif | 11503 #endif |
11523 } | 11504 } |
11524 | 11505 |
11525 } } // namespace v8::internal | 11506 } } // namespace v8::internal |
OLD | NEW |