OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1442 ShortPrint(file); | 1442 ShortPrint(file); |
1443 PrintF(file, " from "); | 1443 PrintF(file, " from "); |
1444 from_elements->ShortPrint(file); | 1444 from_elements->ShortPrint(file); |
1445 PrintF(file, " to "); | 1445 PrintF(file, " to "); |
1446 to_elements->ShortPrint(file); | 1446 to_elements->ShortPrint(file); |
1447 PrintF(file, "\n"); | 1447 PrintF(file, "\n"); |
1448 } | 1448 } |
1449 } | 1449 } |
1450 | 1450 |
1451 | 1451 |
| 1452 void Map::PrintGeneralization(FILE* file, |
| 1453 int modify_index, |
| 1454 int split, |
| 1455 int descriptors, |
| 1456 Representation old_representation, |
| 1457 Representation new_representation) { |
| 1458 PrintF(file, "[generalizing "); |
| 1459 constructor_name()->PrintOn(file); |
| 1460 PrintF(file, "] "); |
| 1461 String::cast(instance_descriptors()->GetKey(modify_index))->PrintOn(file); |
| 1462 PrintF(file, ":%s->%s (+%i maps) [", |
| 1463 old_representation.Mnemonic(), |
| 1464 new_representation.Mnemonic(), |
| 1465 descriptors - split); |
| 1466 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); |
| 1467 PrintF(file, "]\n"); |
| 1468 } |
| 1469 |
| 1470 |
| 1471 void JSObject::PrintInstanceMigration(FILE* file, |
| 1472 Map* original_map, |
| 1473 Map* new_map) { |
| 1474 PrintF(file, "[migrating "); |
| 1475 map()->constructor_name()->PrintOn(file); |
| 1476 PrintF(file, "] "); |
| 1477 DescriptorArray* o = original_map->instance_descriptors(); |
| 1478 DescriptorArray* n = new_map->instance_descriptors(); |
| 1479 for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) { |
| 1480 Representation o_r = o->GetDetails(i).representation(); |
| 1481 Representation n_r = n->GetDetails(i).representation(); |
| 1482 if (!o_r.Equals(n_r)) { |
| 1483 String::cast(o->GetKey(i))->PrintOn(file); |
| 1484 PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic()); |
| 1485 } else if (o->GetDetails(i).type() == CONSTANT && |
| 1486 n->GetDetails(i).type() == FIELD) { |
| 1487 Name* name = o->GetKey(i); |
| 1488 if (name->IsString()) { |
| 1489 String::cast(name)->PrintOn(file); |
| 1490 } else { |
| 1491 PrintF(file, "???"); |
| 1492 } |
| 1493 PrintF(file, " "); |
| 1494 } |
| 1495 } |
| 1496 PrintF(file, "\n"); |
| 1497 } |
| 1498 |
| 1499 |
1452 void HeapObject::HeapObjectShortPrint(StringStream* accumulator) { | 1500 void HeapObject::HeapObjectShortPrint(StringStream* accumulator) { |
1453 Heap* heap = GetHeap(); | 1501 Heap* heap = GetHeap(); |
1454 if (!heap->Contains(this)) { | 1502 if (!heap->Contains(this)) { |
1455 accumulator->Add("!!!INVALID POINTER!!!"); | 1503 accumulator->Add("!!!INVALID POINTER!!!"); |
1456 return; | 1504 return; |
1457 } | 1505 } |
1458 if (!heap->Contains(map())) { | 1506 if (!heap->Contains(map())) { |
1459 accumulator->Add("!!!INVALID MAP!!!"); | 1507 accumulator->Add("!!!INVALID MAP!!!"); |
1460 return; | 1508 return; |
1461 } | 1509 } |
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1776 } | 1824 } |
1777 if (map()->constructor()->IsJSFunction()) { | 1825 if (map()->constructor()->IsJSFunction()) { |
1778 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 1826 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
1779 return String::cast(constructor->shared()->instance_class_name()); | 1827 return String::cast(constructor->shared()->instance_class_name()); |
1780 } | 1828 } |
1781 // If the constructor is not present, return "Object". | 1829 // If the constructor is not present, return "Object". |
1782 return GetHeap()->Object_string(); | 1830 return GetHeap()->Object_string(); |
1783 } | 1831 } |
1784 | 1832 |
1785 | 1833 |
1786 String* JSReceiver::constructor_name() { | 1834 String* Map::constructor_name() { |
1787 if (map()->constructor()->IsJSFunction()) { | 1835 if (constructor()->IsJSFunction()) { |
1788 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 1836 JSFunction* constructor = JSFunction::cast(this->constructor()); |
1789 String* name = String::cast(constructor->shared()->name()); | 1837 String* name = String::cast(constructor->shared()->name()); |
1790 if (name->length() > 0) return name; | 1838 if (name->length() > 0) return name; |
1791 String* inferred_name = constructor->shared()->inferred_name(); | 1839 String* inferred_name = constructor->shared()->inferred_name(); |
1792 if (inferred_name->length() > 0) return inferred_name; | 1840 if (inferred_name->length() > 0) return inferred_name; |
1793 Object* proto = GetPrototype(); | 1841 Object* proto = prototype(); |
1794 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); | 1842 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); |
1795 } | 1843 } |
1796 // TODO(rossberg): what about proxies? | 1844 // TODO(rossberg): what about proxies? |
1797 // If the constructor is not present, return "Object". | 1845 // If the constructor is not present, return "Object". |
1798 return GetHeap()->Object_string(); | 1846 return GetHeap()->Object_string(); |
1799 } | 1847 } |
1800 | 1848 |
1801 | 1849 |
| 1850 String* JSReceiver::constructor_name() { |
| 1851 return map()->constructor_name(); |
| 1852 } |
| 1853 |
| 1854 |
1802 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, | 1855 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, |
1803 Name* name, | 1856 Name* name, |
1804 Object* value, | 1857 Object* value, |
1805 int field_index, | 1858 int field_index, |
1806 Representation representation) { | 1859 Representation representation) { |
1807 // This method is used to transition to a field. If we are transitioning to a | 1860 // This method is used to transition to a field. If we are transitioning to a |
1808 // double field, allocate new storage. | 1861 // double field, allocate new storage. |
1809 Object* storage; | 1862 Object* storage; |
1810 MaybeObject* maybe_storage = | 1863 MaybeObject* maybe_storage = |
1811 value->AllocateNewStorageFor(GetHeap(), representation); | 1864 value->AllocateNewStorageFor(GetHeap(), representation); |
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2619 Representation old_representation = | 2672 Representation old_representation = |
2620 old_descriptors->GetDetails(modify_index).representation(); | 2673 old_descriptors->GetDetails(modify_index).representation(); |
2621 | 2674 |
2622 // It's fine to transition from None to anything but double without any | 2675 // It's fine to transition from None to anything but double without any |
2623 // modification to the object, because the default uninitialized value for | 2676 // modification to the object, because the default uninitialized value for |
2624 // representation None can be overwritten by both smi and tagged values. | 2677 // representation None can be overwritten by both smi and tagged values. |
2625 // Doubles, however, would require a box allocation. | 2678 // Doubles, however, would require a box allocation. |
2626 if (old_representation.IsNone() && | 2679 if (old_representation.IsNone() && |
2627 !new_representation.IsNone() && | 2680 !new_representation.IsNone() && |
2628 !new_representation.IsDouble()) { | 2681 !new_representation.IsDouble()) { |
2629 if (FLAG_trace_generalization) { | |
2630 PrintF("initializing representation %i: %p -> %s\n", | |
2631 modify_index, | |
2632 static_cast<void*>(this), | |
2633 new_representation.Mnemonic()); | |
2634 } | |
2635 old_descriptors->SetRepresentation(modify_index, new_representation); | 2682 old_descriptors->SetRepresentation(modify_index, new_representation); |
2636 return old_map; | 2683 return old_map; |
2637 } | 2684 } |
2638 | 2685 |
2639 int descriptors = old_map->NumberOfOwnDescriptors(); | 2686 int descriptors = old_map->NumberOfOwnDescriptors(); |
2640 Map* root_map = old_map->FindRootMap(); | 2687 Map* root_map = old_map->FindRootMap(); |
2641 | 2688 |
2642 // Check the state of the root map. | 2689 // Check the state of the root map. |
2643 if (!old_map->EquivalentToForTransition(root_map)) { | 2690 if (!old_map->EquivalentToForTransition(root_map)) { |
2644 return CopyGeneralizeAllRepresentations(); | 2691 return CopyGeneralizeAllRepresentations(); |
2645 } | 2692 } |
2646 | 2693 |
2647 int verbatim = root_map->NumberOfOwnDescriptors(); | 2694 int verbatim = root_map->NumberOfOwnDescriptors(); |
2648 | 2695 |
2649 Map* updated = root_map->FindUpdatedMap( | 2696 Map* updated = root_map->FindUpdatedMap( |
2650 verbatim, descriptors, old_descriptors); | 2697 verbatim, descriptors, old_descriptors); |
2651 if (updated == NULL) return CopyGeneralizeAllRepresentations(); | 2698 if (updated == NULL) return CopyGeneralizeAllRepresentations(); |
2652 | 2699 |
2653 DescriptorArray* updated_descriptors = updated->instance_descriptors(); | 2700 DescriptorArray* updated_descriptors = updated->instance_descriptors(); |
2654 | 2701 |
2655 int valid = updated->NumberOfOwnDescriptors(); | 2702 int valid = updated->NumberOfOwnDescriptors(); |
2656 if (updated_descriptors->IsMoreGeneralThan( | 2703 if (updated_descriptors->IsMoreGeneralThan( |
2657 verbatim, valid, descriptors, old_descriptors)) { | 2704 verbatim, valid, descriptors, old_descriptors)) { |
2658 Representation updated_representation = | 2705 Representation updated_representation = |
2659 updated_descriptors->GetDetails(modify_index).representation(); | 2706 updated_descriptors->GetDetails(modify_index).representation(); |
2660 if (new_representation.fits_into(updated_representation)) { | 2707 if (new_representation.fits_into(updated_representation)) { |
2661 if (FLAG_trace_generalization && | 2708 if (FLAG_trace_generalization && |
2662 !(modify_index == 0 && new_representation.IsNone())) { | 2709 !(modify_index == 0 && new_representation.IsNone())) { |
2663 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2710 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2664 PrintF("migrating to existing map %p(%s) -> %p(%s)\n", | 2711 PrintGeneralization(stdout, modify_index, descriptors, descriptors, |
2665 static_cast<void*>(this), | 2712 old_details.representation(), |
2666 old_details.representation().Mnemonic(), | 2713 updated_representation); |
2667 static_cast<void*>(updated), | |
2668 updated_representation.Mnemonic()); | |
2669 } | 2714 } |
2670 return updated; | 2715 return updated; |
2671 } | 2716 } |
2672 } | 2717 } |
2673 | 2718 |
2674 DescriptorArray* new_descriptors; | 2719 DescriptorArray* new_descriptors; |
2675 MaybeObject* maybe_descriptors = updated_descriptors->Merge( | 2720 MaybeObject* maybe_descriptors = updated_descriptors->Merge( |
2676 verbatim, valid, descriptors, old_descriptors); | 2721 verbatim, valid, descriptors, old_descriptors); |
2677 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; | 2722 if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; |
2678 | 2723 |
(...skipping 12 matching lines...) Expand all Loading... |
2691 // This is shadowed by |updated_descriptors| being more general than | 2736 // This is shadowed by |updated_descriptors| being more general than |
2692 // |old_descriptors|. | 2737 // |old_descriptors|. |
2693 ASSERT(descriptors != split_descriptors); | 2738 ASSERT(descriptors != split_descriptors); |
2694 | 2739 |
2695 int descriptor = split_descriptors; | 2740 int descriptor = split_descriptors; |
2696 split_map->DeprecateTarget( | 2741 split_map->DeprecateTarget( |
2697 old_descriptors->GetKey(descriptor), new_descriptors); | 2742 old_descriptors->GetKey(descriptor), new_descriptors); |
2698 | 2743 |
2699 if (FLAG_trace_generalization && | 2744 if (FLAG_trace_generalization && |
2700 !(modify_index == 0 && new_representation.IsNone())) { | 2745 !(modify_index == 0 && new_representation.IsNone())) { |
2701 PrintF("migrating to new map %i: %p(%s) -> %p(%s) (%i steps)\n", | 2746 PrintGeneralization(stdout, modify_index, descriptor, descriptors, |
2702 modify_index, | 2747 old_representation, updated_representation); |
2703 static_cast<void*>(this), | |
2704 old_representation.Mnemonic(), | |
2705 static_cast<void*>(new_descriptors), | |
2706 updated_representation.Mnemonic(), | |
2707 descriptors - descriptor); | |
2708 } | 2748 } |
2709 | 2749 |
2710 Map* new_map = split_map; | 2750 Map* new_map = split_map; |
2711 // Add missing transitions. | 2751 // Add missing transitions. |
2712 for (; descriptor < descriptors; descriptor++) { | 2752 for (; descriptor < descriptors; descriptor++) { |
2713 MaybeObject* maybe_map = new_map->CopyInstallDescriptors( | 2753 MaybeObject* maybe_map = new_map->CopyInstallDescriptors( |
2714 descriptor, new_descriptors); | 2754 descriptor, new_descriptors); |
2715 if (!maybe_map->To(&new_map)) { | 2755 if (!maybe_map->To(&new_map)) { |
2716 // Create a handle for the last created map to ensure it stays alive | 2756 // Create a handle for the last created map to ensure it stays alive |
2717 // during GC. Its descriptor array is too large, but it will be | 2757 // during GC. Its descriptor array is too large, but it will be |
(...skipping 1001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3719 | 3759 |
3720 | 3760 |
3721 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) { | 3761 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) { |
3722 CALL_HEAP_FUNCTION_VOID( | 3762 CALL_HEAP_FUNCTION_VOID( |
3723 object->GetIsolate(), | 3763 object->GetIsolate(), |
3724 object->AllocateStorageForMap(*map)); | 3764 object->AllocateStorageForMap(*map)); |
3725 } | 3765 } |
3726 | 3766 |
3727 | 3767 |
3728 void JSObject::MigrateInstance(Handle<JSObject> object) { | 3768 void JSObject::MigrateInstance(Handle<JSObject> object) { |
3729 if (FLAG_trace_migration) { | |
3730 PrintF("migrating instance %p (%p)\n", | |
3731 static_cast<void*>(*object), | |
3732 static_cast<void*>(object->map())); | |
3733 } | |
3734 CALL_HEAP_FUNCTION_VOID( | 3769 CALL_HEAP_FUNCTION_VOID( |
3735 object->GetIsolate(), | 3770 object->GetIsolate(), |
3736 object->MigrateInstance()); | 3771 object->MigrateInstance()); |
3737 } | 3772 } |
3738 | 3773 |
3739 | 3774 |
3740 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { | 3775 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { |
3741 if (FLAG_trace_migration) { | |
3742 PrintF("migrating instance (no new maps) %p (%p)\n", | |
3743 static_cast<void*>(*object), | |
3744 static_cast<void*>(object->map())); | |
3745 } | |
3746 CALL_HEAP_FUNCTION( | 3776 CALL_HEAP_FUNCTION( |
3747 object->GetIsolate(), | 3777 object->GetIsolate(), |
3748 object->MigrateInstance(), | 3778 object->MigrateInstance(), |
3749 Object); | 3779 Object); |
3750 } | 3780 } |
3751 | 3781 |
3752 | 3782 |
3753 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map, | 3783 Handle<Map> Map::GeneralizeRepresentation(Handle<Map> map, |
3754 int modify_index, | 3784 int modify_index, |
3755 Representation representation) { | 3785 Representation representation) { |
(...skipping 12221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15977 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16007 #define ERROR_MESSAGES_TEXTS(C, T) T, |
15978 static const char* error_messages_[] = { | 16008 static const char* error_messages_[] = { |
15979 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16009 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
15980 }; | 16010 }; |
15981 #undef ERROR_MESSAGES_TEXTS | 16011 #undef ERROR_MESSAGES_TEXTS |
15982 return error_messages_[reason]; | 16012 return error_messages_[reason]; |
15983 } | 16013 } |
15984 | 16014 |
15985 | 16015 |
15986 } } // namespace v8::internal | 16016 } } // namespace v8::internal |
OLD | NEW |