| 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 1134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1145 environment()->Push(elements); | 1145 environment()->Push(elements); |
| 1146 capacity_checker.End(); | 1146 capacity_checker.End(); |
| 1147 | 1147 |
| 1148 if (is_js_array) { | 1148 if (is_js_array) { |
| 1149 HValue* new_length = AddInstruction( | 1149 HValue* new_length = AddInstruction( |
| 1150 HAdd::New(zone, context, length, graph_->GetConstant1())); | 1150 HAdd::New(zone, context, length, graph_->GetConstant1())); |
| 1151 new_length->ChangeRepresentation(Representation::Integer32()); | 1151 new_length->ChangeRepresentation(Representation::Integer32()); |
| 1152 new_length->ClearFlag(HValue::kCanOverflow); | 1152 new_length->ClearFlag(HValue::kCanOverflow); |
| 1153 | 1153 |
| 1154 Factory* factory = isolate()->factory(); | 1154 Factory* factory = isolate()->factory(); |
| 1155 Representation representation = IsFastElementsKind(kind) |
| 1156 ? Representation::Smi() : Representation::Tagged(); |
| 1155 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( | 1157 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( |
| 1156 object, | 1158 object, |
| 1157 factory->length_field_string(), | 1159 factory->length_field_string(), |
| 1158 new_length, true, | 1160 new_length, true, |
| 1161 representation, |
| 1159 JSArray::kLengthOffset)); | 1162 JSArray::kLengthOffset)); |
| 1160 length_store->SetGVNFlag(kChangesArrayLengths); | 1163 length_store->SetGVNFlag(kChangesArrayLengths); |
| 1161 } | 1164 } |
| 1162 | 1165 |
| 1163 length_checker.Else(); | 1166 length_checker.Else(); |
| 1164 | 1167 |
| 1165 AddBoundsCheck(key, length, ALLOW_SMI_KEY); | 1168 AddBoundsCheck(key, length, ALLOW_SMI_KEY); |
| 1166 environment()->Push(elements); | 1169 environment()->Push(elements); |
| 1167 | 1170 |
| 1168 length_checker.End(); | 1171 length_checker.End(); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1369 ElementsKind kind, | 1372 ElementsKind kind, |
| 1370 HValue* capacity) { | 1373 HValue* capacity) { |
| 1371 Zone* zone = this->zone(); | 1374 Zone* zone = this->zone(); |
| 1372 Factory* factory = isolate()->factory(); | 1375 Factory* factory = isolate()->factory(); |
| 1373 Handle<Map> map = IsFastDoubleElementsKind(kind) | 1376 Handle<Map> map = IsFastDoubleElementsKind(kind) |
| 1374 ? factory->fixed_double_array_map() | 1377 ? factory->fixed_double_array_map() |
| 1375 : factory->fixed_array_map(); | 1378 : factory->fixed_array_map(); |
| 1376 BuildStoreMap(elements, map); | 1379 BuildStoreMap(elements, map); |
| 1377 | 1380 |
| 1378 Handle<String> fixed_array_length_field_name = factory->length_field_string(); | 1381 Handle<String> fixed_array_length_field_name = factory->length_field_string(); |
| 1382 Representation representation = IsFastElementsKind(kind) |
| 1383 ? Representation::Smi() : Representation::Tagged(); |
| 1379 HInstruction* store_length = | 1384 HInstruction* store_length = |
| 1380 new(zone) HStoreNamedField(elements, fixed_array_length_field_name, | 1385 new(zone) HStoreNamedField(elements, fixed_array_length_field_name, |
| 1381 capacity, true, FixedArray::kLengthOffset); | 1386 capacity, true, representation, |
| 1387 FixedArray::kLengthOffset); |
| 1382 AddInstruction(store_length); | 1388 AddInstruction(store_length); |
| 1383 } | 1389 } |
| 1384 | 1390 |
| 1385 | 1391 |
| 1386 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, | 1392 HValue* HGraphBuilder::BuildAllocateAndInitializeElements(HValue* context, |
| 1387 ElementsKind kind, | 1393 ElementsKind kind, |
| 1388 HValue* capacity) { | 1394 HValue* capacity) { |
| 1389 HValue* new_elements = BuildAllocateElements(context, kind, capacity); | 1395 HValue* new_elements = BuildAllocateElements(context, kind, capacity); |
| 1390 BuildInitializeElements(new_elements, kind, capacity); | 1396 BuildInitializeElements(new_elements, kind, capacity); |
| 1391 return new_elements; | 1397 return new_elements; |
| 1392 } | 1398 } |
| 1393 | 1399 |
| 1394 | 1400 |
| 1395 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, | 1401 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, |
| 1396 HValue* map) { | 1402 HValue* map) { |
| 1397 Zone* zone = this->zone(); | 1403 Zone* zone = this->zone(); |
| 1398 Factory* factory = isolate()->factory(); | 1404 Factory* factory = isolate()->factory(); |
| 1399 Handle<String> map_field_name = factory->map_field_string(); | 1405 Handle<String> map_field_name = factory->map_field_string(); |
| 1400 HInstruction* store_map = | 1406 HInstruction* store_map = |
| 1401 new(zone) HStoreNamedField(object, map_field_name, map, | 1407 new(zone) HStoreNamedField(object, map_field_name, map, |
| 1402 true, JSObject::kMapOffset); | 1408 true, Representation::Tagged(), |
| 1409 JSObject::kMapOffset); |
| 1403 store_map->SetGVNFlag(kChangesMaps); | 1410 store_map->SetGVNFlag(kChangesMaps); |
| 1404 AddInstruction(store_map); | 1411 AddInstruction(store_map); |
| 1405 return store_map; | 1412 return store_map; |
| 1406 } | 1413 } |
| 1407 | 1414 |
| 1408 | 1415 |
| 1409 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, | 1416 HInstruction* HGraphBuilder::BuildStoreMap(HValue* object, |
| 1410 Handle<Map> map) { | 1417 Handle<Map> map) { |
| 1411 Zone* zone = this->zone(); | 1418 Zone* zone = this->zone(); |
| 1412 HValue* map_constant = | 1419 HValue* map_constant = |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1473 BuildAllocateAndInitializeElements(context, kind, new_capacity); | 1480 BuildAllocateAndInitializeElements(context, kind, new_capacity); |
| 1474 | 1481 |
| 1475 BuildCopyElements(context, elements, kind, | 1482 BuildCopyElements(context, elements, kind, |
| 1476 new_elements, kind, | 1483 new_elements, kind, |
| 1477 length, new_capacity); | 1484 length, new_capacity); |
| 1478 | 1485 |
| 1479 Factory* factory = isolate()->factory(); | 1486 Factory* factory = isolate()->factory(); |
| 1480 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( | 1487 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( |
| 1481 object, | 1488 object, |
| 1482 factory->elements_field_string(), | 1489 factory->elements_field_string(), |
| 1483 new_elements, true, | 1490 new_elements, true, Representation::Tagged(), |
| 1484 JSArray::kElementsOffset)); | 1491 JSArray::kElementsOffset)); |
| 1485 elements_store->SetGVNFlag(kChangesElementsPointer); | 1492 elements_store->SetGVNFlag(kChangesElementsPointer); |
| 1486 | 1493 |
| 1487 return new_elements; | 1494 return new_elements; |
| 1488 } | 1495 } |
| 1489 | 1496 |
| 1490 | 1497 |
| 1491 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, | 1498 void HGraphBuilder::BuildFillElementsWithHole(HValue* context, |
| 1492 HValue* elements, | 1499 HValue* elements, |
| 1493 ElementsKind elements_kind, | 1500 ElementsKind elements_kind, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1590 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); | 1597 AddInstruction(new(zone) HConstant(size, Representation::Integer32())); |
| 1591 HInstruction* object = | 1598 HInstruction* object = |
| 1592 AddInstruction(new(zone) HAllocate(context, | 1599 AddInstruction(new(zone) HAllocate(context, |
| 1593 size_in_bytes, | 1600 size_in_bytes, |
| 1594 HType::JSObject(), | 1601 HType::JSObject(), |
| 1595 allocate_flags)); | 1602 allocate_flags)); |
| 1596 | 1603 |
| 1597 // Copy the JS array part. | 1604 // Copy the JS array part. |
| 1598 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { | 1605 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
| 1599 if ((i != JSArray::kElementsOffset) || (length == 0)) { | 1606 if ((i != JSArray::kElementsOffset) || (length == 0)) { |
| 1600 HInstruction* value = | 1607 HInstruction* value = AddInstruction(new(zone) HLoadNamedField( |
| 1601 AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i)); | 1608 boilerplate, true, Representation::Tagged(), i)); |
| 1602 if (i != JSArray::kMapOffset) { | 1609 if (i != JSArray::kMapOffset) { |
| 1603 AddInstruction(new(zone) HStoreNamedField(object, | 1610 AddInstruction(new(zone) HStoreNamedField(object, |
| 1604 factory->empty_string(), | 1611 factory->empty_string(), |
| 1605 value, | 1612 value, true, |
| 1606 true, i)); | 1613 Representation::Tagged(), i)); |
| 1607 } else { | 1614 } else { |
| 1608 BuildStoreMap(object, value); | 1615 BuildStoreMap(object, value); |
| 1609 } | 1616 } |
| 1610 } | 1617 } |
| 1611 } | 1618 } |
| 1612 | 1619 |
| 1613 // Create an allocation site info if requested. | 1620 // Create an allocation site info if requested. |
| 1614 if (mode == TRACK_ALLOCATION_SITE) { | 1621 if (mode == TRACK_ALLOCATION_SITE) { |
| 1615 HValue* alloc_site = | 1622 HValue* alloc_site = |
| 1616 AddInstruction(new(zone) HInnerAllocatedObject(object, JSArray::kSize)); | 1623 AddInstruction(new(zone) HInnerAllocatedObject(object, JSArray::kSize)); |
| 1617 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); | 1624 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); |
| 1618 BuildStoreMap(alloc_site, alloc_site_map); | 1625 BuildStoreMap(alloc_site, alloc_site_map); |
| 1619 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; | 1626 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; |
| 1620 AddInstruction(new(zone) HStoreNamedField(alloc_site, | 1627 AddInstruction(new(zone) HStoreNamedField(alloc_site, |
| 1621 factory->empty_string(), | 1628 factory->empty_string(), |
| 1622 boilerplate, | 1629 boilerplate, true, |
| 1623 true, alloc_payload_offset)); | 1630 Representation::Tagged(), |
| 1631 alloc_payload_offset)); |
| 1624 } | 1632 } |
| 1625 | 1633 |
| 1626 if (length > 0) { | 1634 if (length > 0) { |
| 1627 // Get hold of the elements array of the boilerplate and setup the | 1635 // Get hold of the elements array of the boilerplate and setup the |
| 1628 // elements pointer in the resulting object. | 1636 // elements pointer in the resulting object. |
| 1629 HValue* boilerplate_elements = | 1637 HValue* boilerplate_elements = |
| 1630 AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); | 1638 AddInstruction(new(zone) HLoadElements(boilerplate, NULL)); |
| 1631 HValue* object_elements = | 1639 HValue* object_elements = |
| 1632 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); | 1640 AddInstruction(new(zone) HInnerAllocatedObject(object, elems_offset)); |
| 1633 AddInstruction(new(zone) HStoreNamedField(object, | 1641 AddInstruction(new(zone) HStoreNamedField(object, |
| 1634 factory->elements_field_string(), | 1642 factory->elements_field_string(), |
| 1635 object_elements, | 1643 object_elements, true, |
| 1636 true, JSObject::kElementsOffset)); | 1644 Representation::Tagged(), |
| 1645 JSObject::kElementsOffset)); |
| 1637 | 1646 |
| 1638 // Copy the elements array header. | 1647 // Copy the elements array header. |
| 1639 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { | 1648 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { |
| 1640 HInstruction* value = | 1649 HInstruction* value = |
| 1641 AddInstruction(new(zone) HLoadNamedField(boilerplate_elements, | 1650 AddInstruction(new(zone) HLoadNamedField( |
| 1642 true, i)); | 1651 boilerplate_elements, true, Representation::Tagged(), i)); |
| 1643 AddInstruction(new(zone) HStoreNamedField(object_elements, | 1652 AddInstruction(new(zone) HStoreNamedField(object_elements, |
| 1644 factory->empty_string(), | 1653 factory->empty_string(), |
| 1645 value, | 1654 value, true, |
| 1646 true, i)); | 1655 Representation::Tagged(), i)); |
| 1647 } | 1656 } |
| 1648 | 1657 |
| 1649 // Copy the elements array contents. | 1658 // Copy the elements array contents. |
| 1650 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold | 1659 // TODO(mstarzinger): Teach HGraphBuilder::BuildCopyElements to unfold |
| 1651 // copying loops with constant length up to a given boundary and use this | 1660 // copying loops with constant length up to a given boundary and use this |
| 1652 // helper here instead. | 1661 // helper here instead. |
| 1653 for (int i = 0; i < length; i++) { | 1662 for (int i = 0; i < length; i++) { |
| 1654 HValue* key_constant = | 1663 HValue* key_constant = |
| 1655 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); | 1664 AddInstruction(new(zone) HConstant(i, Representation::Integer32())); |
| 1656 HInstruction* value = | 1665 HInstruction* value = |
| (...skipping 4910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6567 | 6576 |
| 6568 // 2nd chance: A store into a non-existent field can still be inlined if we | 6577 // 2nd chance: A store into a non-existent field can still be inlined if we |
| 6569 // have a matching transition and some room left in the object. | 6578 // have a matching transition and some room left in the object. |
| 6570 type->LookupTransition(NULL, *name, lookup); | 6579 type->LookupTransition(NULL, *name, lookup); |
| 6571 return lookup->IsTransitionToField(*type) && | 6580 return lookup->IsTransitionToField(*type) && |
| 6572 (type->unused_property_fields() > 0); | 6581 (type->unused_property_fields() > 0); |
| 6573 } | 6582 } |
| 6574 | 6583 |
| 6575 | 6584 |
| 6576 static int ComputeLoadStoreFieldIndex(Handle<Map> type, | 6585 static int ComputeLoadStoreFieldIndex(Handle<Map> type, |
| 6577 Handle<String> name, | |
| 6578 LookupResult* lookup) { | 6586 LookupResult* lookup) { |
| 6579 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*type)); | 6587 ASSERT(lookup->IsField() || lookup->IsTransitionToField(*type)); |
| 6580 if (lookup->IsField()) { | 6588 if (lookup->IsField()) { |
| 6581 return lookup->GetLocalFieldIndexFromMap(*type); | 6589 return lookup->GetLocalFieldIndexFromMap(*type); |
| 6582 } else { | 6590 } else { |
| 6583 Map* transition = lookup->GetTransitionMapFromMap(*type); | 6591 Map* transition = lookup->GetTransitionMapFromMap(*type); |
| 6584 return transition->PropertyIndexFor(*name) - type->inobject_properties(); | 6592 int descriptor = transition->LastAdded(); |
| 6593 int index = transition->instance_descriptors()->GetFieldIndex(descriptor); |
| 6594 return index - type->inobject_properties(); |
| 6585 } | 6595 } |
| 6586 } | 6596 } |
| 6587 | 6597 |
| 6598 |
| 6599 static Representation ComputeLoadStoreRepresentation(Handle<Map> type, |
| 6600 LookupResult* lookup) { |
| 6601 if (lookup->IsField()) { |
| 6602 return lookup->representation(); |
| 6603 } else { |
| 6604 Map* transition = lookup->GetTransitionMapFromMap(*type); |
| 6605 int descriptor = transition->LastAdded(); |
| 6606 PropertyDetails details = |
| 6607 transition->instance_descriptors()->GetDetails(descriptor); |
| 6608 return details.representation(); |
| 6609 } |
| 6610 } |
| 6611 |
| 6588 | 6612 |
| 6589 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { | 6613 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) { |
| 6590 AddInstruction(new(zone()) HCheckNonSmi(object)); | 6614 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| 6591 AddInstruction(HCheckMaps::New(object, map, zone())); | 6615 AddInstruction(HCheckMaps::New(object, map, zone())); |
| 6592 } | 6616 } |
| 6593 | 6617 |
| 6594 | 6618 |
| 6595 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, | 6619 void HOptimizedGraphBuilder::AddCheckMapsWithTransitions(HValue* object, |
| 6596 Handle<Map> map) { | 6620 Handle<Map> map) { |
| 6597 AddInstruction(new(zone()) HCheckNonSmi(object)); | 6621 AddInstruction(new(zone()) HCheckNonSmi(object)); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6629 } | 6653 } |
| 6630 ASSERT(proto->GetPrototype(isolate())->IsNull()); | 6654 ASSERT(proto->GetPrototype(isolate())->IsNull()); |
| 6631 } | 6655 } |
| 6632 ASSERT(proto->IsJSObject()); | 6656 ASSERT(proto->IsJSObject()); |
| 6633 AddInstruction(new(zone()) HCheckPrototypeMaps( | 6657 AddInstruction(new(zone()) HCheckPrototypeMaps( |
| 6634 Handle<JSObject>(JSObject::cast(map->prototype())), | 6658 Handle<JSObject>(JSObject::cast(map->prototype())), |
| 6635 Handle<JSObject>(JSObject::cast(proto)), | 6659 Handle<JSObject>(JSObject::cast(proto)), |
| 6636 zone())); | 6660 zone())); |
| 6637 } | 6661 } |
| 6638 | 6662 |
| 6639 int index = ComputeLoadStoreFieldIndex(map, name, lookup); | 6663 int index = ComputeLoadStoreFieldIndex(map, lookup); |
| 6640 bool is_in_object = index < 0; | 6664 bool is_in_object = index < 0; |
| 6665 Representation representation = ComputeLoadStoreRepresentation(map, lookup); |
| 6641 int offset = index * kPointerSize; | 6666 int offset = index * kPointerSize; |
| 6642 if (index < 0) { | 6667 if (index < 0) { |
| 6643 // Negative property indices are in-object properties, indexed | 6668 // Negative property indices are in-object properties, indexed |
| 6644 // from the end of the fixed part of the object. | 6669 // from the end of the fixed part of the object. |
| 6645 offset += map->instance_size(); | 6670 offset += map->instance_size(); |
| 6646 } else { | 6671 } else { |
| 6647 offset += FixedArray::kHeaderSize; | 6672 offset += FixedArray::kHeaderSize; |
| 6648 } | 6673 } |
| 6649 HStoreNamedField* instr = | 6674 HStoreNamedField* instr = new(zone()) HStoreNamedField( |
| 6650 new(zone()) HStoreNamedField(object, name, value, is_in_object, offset); | 6675 object, name, value, is_in_object, representation, offset); |
| 6651 if (lookup->IsTransitionToField(*map)) { | 6676 if (lookup->IsTransitionToField(*map)) { |
| 6652 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); | 6677 Handle<Map> transition(lookup->GetTransitionMapFromMap(*map)); |
| 6653 instr->set_transition(transition); | 6678 instr->set_transition(transition); |
| 6654 // TODO(fschneider): Record the new map type of the object in the IR to | 6679 // TODO(fschneider): Record the new map type of the object in the IR to |
| 6655 // enable elimination of redundant checks after the transition store. | 6680 // enable elimination of redundant checks after the transition store. |
| 6656 instr->SetGVNFlag(kChangesMaps); | 6681 instr->SetGVNFlag(kChangesMaps); |
| 6657 } | 6682 } |
| 6658 return instr; | 6683 return instr; |
| 6659 } | 6684 } |
| 6660 | 6685 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6736 bool is_monomorphic_field = true; | 6761 bool is_monomorphic_field = true; |
| 6737 | 6762 |
| 6738 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name)) | 6763 if (HandlePolymorphicArrayLengthLoad(expr, object, types, name)) |
| 6739 return; | 6764 return; |
| 6740 | 6765 |
| 6741 Handle<Map> map; | 6766 Handle<Map> map; |
| 6742 LookupResult lookup(isolate()); | 6767 LookupResult lookup(isolate()); |
| 6743 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { | 6768 for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { |
| 6744 map = types->at(i); | 6769 map = types->at(i); |
| 6745 if (ComputeLoadStoreField(map, name, &lookup, false)) { | 6770 if (ComputeLoadStoreField(map, name, &lookup, false)) { |
| 6746 int index = ComputeLoadStoreFieldIndex(map, name, &lookup); | 6771 int index = ComputeLoadStoreFieldIndex(map, &lookup); |
| 6747 bool is_in_object = index < 0; | 6772 bool is_in_object = index < 0; |
| 6748 int offset = index * kPointerSize; | 6773 int offset = index * kPointerSize; |
| 6749 if (index < 0) { | 6774 if (index < 0) { |
| 6750 // Negative property indices are in-object properties, indexed | 6775 // Negative property indices are in-object properties, indexed |
| 6751 // from the end of the fixed part of the object. | 6776 // from the end of the fixed part of the object. |
| 6752 offset += map->instance_size(); | 6777 offset += map->instance_size(); |
| 6753 } else { | 6778 } else { |
| 6754 offset += FixedArray::kHeaderSize; | 6779 offset += FixedArray::kHeaderSize; |
| 6755 } | 6780 } |
| 6756 if (count == 0) { | 6781 if (count == 0) { |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7327 AddSimulate(expr->id()); | 7352 AddSimulate(expr->id()); |
| 7328 current_block()->FinishExit(new(zone()) HAbnormalExit); | 7353 current_block()->FinishExit(new(zone()) HAbnormalExit); |
| 7329 set_current_block(NULL); | 7354 set_current_block(NULL); |
| 7330 } | 7355 } |
| 7331 | 7356 |
| 7332 | 7357 |
| 7333 HLoadNamedField* HOptimizedGraphBuilder::BuildLoadNamedField( | 7358 HLoadNamedField* HOptimizedGraphBuilder::BuildLoadNamedField( |
| 7334 HValue* object, | 7359 HValue* object, |
| 7335 Handle<Map> map, | 7360 Handle<Map> map, |
| 7336 LookupResult* lookup) { | 7361 LookupResult* lookup) { |
| 7362 Representation representation = lookup->representation(); |
| 7337 int index = lookup->GetLocalFieldIndexFromMap(*map); | 7363 int index = lookup->GetLocalFieldIndexFromMap(*map); |
| 7338 if (index < 0) { | 7364 if (index < 0) { |
| 7339 // Negative property indices are in-object properties, indexed | 7365 // Negative property indices are in-object properties, indexed |
| 7340 // from the end of the fixed part of the object. | 7366 // from the end of the fixed part of the object. |
| 7341 int offset = (index * kPointerSize) + map->instance_size(); | 7367 int offset = (index * kPointerSize) + map->instance_size(); |
| 7342 return new(zone()) HLoadNamedField(object, true, offset); | 7368 return new(zone()) HLoadNamedField(object, true, representation, offset); |
| 7343 } else { | 7369 } else { |
| 7344 // Non-negative property indices are in the properties array. | 7370 // Non-negative property indices are in the properties array. |
| 7345 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; | 7371 int offset = (index * kPointerSize) + FixedArray::kHeaderSize; |
| 7346 return new(zone()) HLoadNamedField(object, false, offset); | 7372 return new(zone()) HLoadNamedField(object, false, representation, offset); |
| 7347 } | 7373 } |
| 7348 } | 7374 } |
| 7349 | 7375 |
| 7350 | 7376 |
| 7351 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( | 7377 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
| 7352 HValue* object, | 7378 HValue* object, |
| 7353 Handle<String> name, | 7379 Handle<String> name, |
| 7354 Property* expr) { | 7380 Property* expr) { |
| 7355 if (expr->IsUninitialized()) { | 7381 if (expr->IsUninitialized()) { |
| 7356 AddSoftDeoptimize(); | 7382 AddSoftDeoptimize(); |
| (...skipping 2956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10313 Handle<Object> value = | 10339 Handle<Object> value = |
| 10314 Handle<Object>(boilerplate_object->InObjectPropertyAt(i), | 10340 Handle<Object>(boilerplate_object->InObjectPropertyAt(i), |
| 10315 isolate()); | 10341 isolate()); |
| 10316 if (value->IsJSObject()) { | 10342 if (value->IsJSObject()) { |
| 10317 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 10343 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 10318 Handle<JSObject> original_value_object = Handle<JSObject>::cast( | 10344 Handle<JSObject> original_value_object = Handle<JSObject>::cast( |
| 10319 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(i), | 10345 Handle<Object>(original_boilerplate_object->InObjectPropertyAt(i), |
| 10320 isolate())); | 10346 isolate())); |
| 10321 HInstruction* value_instruction = | 10347 HInstruction* value_instruction = |
| 10322 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); | 10348 AddInstruction(new(zone) HInnerAllocatedObject(target, *offset)); |
| 10349 // TODO(verwaest): choose correct storage. |
| 10323 AddInstruction(new(zone) HStoreNamedField( | 10350 AddInstruction(new(zone) HStoreNamedField( |
| 10324 object_properties, factory->unknown_field_string(), value_instruction, | 10351 object_properties, factory->unknown_field_string(), value_instruction, |
| 10325 true, boilerplate_object->GetInObjectPropertyOffset(i))); | 10352 true, Representation::Tagged(), |
| 10353 boilerplate_object->GetInObjectPropertyOffset(i))); |
| 10326 BuildEmitDeepCopy(value_object, original_value_object, target, | 10354 BuildEmitDeepCopy(value_object, original_value_object, target, |
| 10327 offset, DONT_TRACK_ALLOCATION_SITE); | 10355 offset, DONT_TRACK_ALLOCATION_SITE); |
| 10328 } else { | 10356 } else { |
| 10357 // TODO(verwaest): choose correct storage. |
| 10329 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( | 10358 HInstruction* value_instruction = AddInstruction(new(zone) HConstant( |
| 10330 value, Representation::Tagged())); | 10359 value, Representation::Tagged())); |
| 10331 AddInstruction(new(zone) HStoreNamedField( | 10360 AddInstruction(new(zone) HStoreNamedField( |
| 10332 object_properties, factory->unknown_field_string(), value_instruction, | 10361 object_properties, factory->unknown_field_string(), value_instruction, |
| 10333 true, boilerplate_object->GetInObjectPropertyOffset(i))); | 10362 true, Representation::Tagged(), |
| 10363 boilerplate_object->GetInObjectPropertyOffset(i))); |
| 10334 } | 10364 } |
| 10335 } | 10365 } |
| 10336 | 10366 |
| 10337 // Build Allocation Site Info if desired | 10367 // Build Allocation Site Info if desired |
| 10338 if (create_allocation_site_info) { | 10368 if (create_allocation_site_info) { |
| 10339 HValue* alloc_site = | 10369 HValue* alloc_site = |
| 10340 AddInstruction(new(zone) HInnerAllocatedObject(target, JSArray::kSize)); | 10370 AddInstruction(new(zone) HInnerAllocatedObject(target, JSArray::kSize)); |
| 10341 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); | 10371 Handle<Map> alloc_site_map(isolate()->heap()->allocation_site_info_map()); |
| 10342 BuildStoreMap(alloc_site, alloc_site_map); | 10372 BuildStoreMap(alloc_site, alloc_site_map); |
| 10343 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; | 10373 int alloc_payload_offset = AllocationSiteInfo::kPayloadOffset; |
| 10344 AddInstruction(new(zone) HStoreNamedField(alloc_site, | 10374 AddInstruction(new(zone) HStoreNamedField( |
| 10345 factory->payload_string(), | 10375 alloc_site, |
| 10346 original_boilerplate, | 10376 factory->payload_string(), |
| 10347 true, alloc_payload_offset)); | 10377 original_boilerplate, |
| 10378 true, Representation::Tagged(), alloc_payload_offset)); |
| 10348 } | 10379 } |
| 10349 | 10380 |
| 10350 if (object_elements != NULL) { | 10381 if (object_elements != NULL) { |
| 10351 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( | 10382 HInstruction* boilerplate_elements = AddInstruction(new(zone) HConstant( |
| 10352 elements, Representation::Tagged())); | 10383 elements, Representation::Tagged())); |
| 10353 | 10384 |
| 10354 int elements_length = elements->length(); | 10385 int elements_length = elements->length(); |
| 10355 HValue* object_elements_length = | 10386 HValue* object_elements_length = |
| 10356 AddInstruction(new(zone) HConstant( | 10387 AddInstruction(new(zone) HConstant( |
| 10357 elements_length, Representation::Integer32())); | 10388 elements_length, Representation::Integer32())); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10426 elements_field, Representation::Tagged())); | 10457 elements_field, Representation::Tagged())); |
| 10427 } else { | 10458 } else { |
| 10428 elements = AddInstruction(new(zone) HInnerAllocatedObject( | 10459 elements = AddInstruction(new(zone) HInnerAllocatedObject( |
| 10429 target, elements_offset)); | 10460 target, elements_offset)); |
| 10430 result = elements; | 10461 result = elements; |
| 10431 } | 10462 } |
| 10432 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( | 10463 HInstruction* elements_store = AddInstruction(new(zone) HStoreNamedField( |
| 10433 object_header, | 10464 object_header, |
| 10434 factory->elements_field_string(), | 10465 factory->elements_field_string(), |
| 10435 elements, | 10466 elements, |
| 10436 true, JSObject::kElementsOffset)); | 10467 true, Representation::Tagged(), JSObject::kElementsOffset)); |
| 10437 elements_store->SetGVNFlag(kChangesElementsPointer); | 10468 elements_store->SetGVNFlag(kChangesElementsPointer); |
| 10438 | 10469 |
| 10439 Handle<Object> properties_field = | 10470 Handle<Object> properties_field = |
| 10440 Handle<Object>(boilerplate_object->properties(), isolate()); | 10471 Handle<Object>(boilerplate_object->properties(), isolate()); |
| 10441 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); | 10472 ASSERT(*properties_field == isolate()->heap()->empty_fixed_array()); |
| 10442 HInstruction* properties = AddInstruction(new(zone) HConstant( | 10473 HInstruction* properties = AddInstruction(new(zone) HConstant( |
| 10443 properties_field, Representation::None())); | 10474 properties_field, Representation::None())); |
| 10444 AddInstruction(new(zone) HStoreNamedField(object_header, | 10475 AddInstruction(new(zone) HStoreNamedField(object_header, |
| 10445 factory->empty_string(), | 10476 factory->empty_string(), |
| 10446 properties, | 10477 properties, true, |
| 10447 true, JSObject::kPropertiesOffset)); | 10478 Representation::Tagged(), |
| 10479 JSObject::kPropertiesOffset)); |
| 10448 | 10480 |
| 10449 if (boilerplate_object->IsJSArray()) { | 10481 if (boilerplate_object->IsJSArray()) { |
| 10450 Handle<JSArray> boilerplate_array = | 10482 Handle<JSArray> boilerplate_array = |
| 10451 Handle<JSArray>::cast(boilerplate_object); | 10483 Handle<JSArray>::cast(boilerplate_object); |
| 10452 Handle<Object> length_field = | 10484 Handle<Object> length_field = |
| 10453 Handle<Object>(boilerplate_array->length(), isolate()); | 10485 Handle<Object>(boilerplate_array->length(), isolate()); |
| 10454 HInstruction* length = AddInstruction(new(zone) HConstant( | 10486 HInstruction* length = AddInstruction(new(zone) HConstant( |
| 10455 length_field, Representation::None())); | 10487 length_field, Representation::None())); |
| 10488 ASSERT(boilerplate_array->length()->IsSmi()); |
| 10489 Representation representation = |
| 10490 IsFastElementsKind(boilerplate_array->GetElementsKind()) |
| 10491 ? Representation::Smi() : Representation::Tagged(); |
| 10456 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( | 10492 HInstruction* length_store = AddInstruction(new(zone) HStoreNamedField( |
| 10457 object_header, | 10493 object_header, |
| 10458 factory->length_field_string(), | 10494 factory->length_field_string(), |
| 10459 length, | 10495 length, |
| 10460 true, JSArray::kLengthOffset)); | 10496 true, representation, JSArray::kLengthOffset)); |
| 10461 length_store->SetGVNFlag(kChangesArrayLengths); | 10497 length_store->SetGVNFlag(kChangesArrayLengths); |
| 10462 } | 10498 } |
| 10463 | 10499 |
| 10464 return result; | 10500 return result; |
| 10465 } | 10501 } |
| 10466 | 10502 |
| 10467 | 10503 |
| 10468 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 10504 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
| 10469 ASSERT(!HasStackOverflow()); | 10505 ASSERT(!HasStackOverflow()); |
| 10470 ASSERT(current_block() != NULL); | 10506 ASSERT(current_block() != NULL); |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10843 current_block()->Finish(typecheck); | 10879 current_block()->Finish(typecheck); |
| 10844 not_js_value->Goto(join); | 10880 not_js_value->Goto(join); |
| 10845 | 10881 |
| 10846 // Create in-object property store to kValueOffset. | 10882 // Create in-object property store to kValueOffset. |
| 10847 set_current_block(if_js_value); | 10883 set_current_block(if_js_value); |
| 10848 Handle<String> name = isolate()->factory()->undefined_string(); | 10884 Handle<String> name = isolate()->factory()->undefined_string(); |
| 10849 AddInstruction(new(zone()) HStoreNamedField(object, | 10885 AddInstruction(new(zone()) HStoreNamedField(object, |
| 10850 name, | 10886 name, |
| 10851 value, | 10887 value, |
| 10852 true, // in-object store. | 10888 true, // in-object store. |
| 10889 Representation::Tagged(), |
| 10853 JSValue::kValueOffset)); | 10890 JSValue::kValueOffset)); |
| 10854 if_js_value->Goto(join); | 10891 if_js_value->Goto(join); |
| 10855 join->SetJoinId(call->id()); | 10892 join->SetJoinId(call->id()); |
| 10856 set_current_block(join); | 10893 set_current_block(join); |
| 10857 return ast_context()->ReturnValue(value); | 10894 return ast_context()->ReturnValue(value); |
| 10858 } | 10895 } |
| 10859 | 10896 |
| 10860 | 10897 |
| 10861 // Fast support for charCodeAt(n). | 10898 // Fast support for charCodeAt(n). |
| 10862 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { | 10899 void HOptimizedGraphBuilder::GenerateStringCharCodeAt(CallRuntime* call) { |
| (...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11809 } | 11846 } |
| 11810 } | 11847 } |
| 11811 | 11848 |
| 11812 #ifdef DEBUG | 11849 #ifdef DEBUG |
| 11813 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 11850 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 11814 if (allocator_ != NULL) allocator_->Verify(); | 11851 if (allocator_ != NULL) allocator_->Verify(); |
| 11815 #endif | 11852 #endif |
| 11816 } | 11853 } |
| 11817 | 11854 |
| 11818 } } // namespace v8::internal | 11855 } } // namespace v8::internal |
| OLD | NEW |