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 |