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