| 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 15 matching lines...) Expand all Loading... |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "accessors.h" | 30 #include "accessors.h" |
| 31 #include "allocation-site-scopes.h" | 31 #include "allocation-site-scopes.h" |
| 32 #include "api.h" | 32 #include "api.h" |
| 33 #include "arguments.h" | 33 #include "arguments.h" |
| 34 #include "bootstrapper.h" | 34 #include "bootstrapper.h" |
| 35 #include "codegen.h" | 35 #include "codegen.h" |
| 36 #include "code-stubs.h" |
| 36 #include "cpu-profiler.h" | 37 #include "cpu-profiler.h" |
| 37 #include "debug.h" | 38 #include "debug.h" |
| 38 #include "deoptimizer.h" | 39 #include "deoptimizer.h" |
| 39 #include "date.h" | 40 #include "date.h" |
| 40 #include "elements.h" | 41 #include "elements.h" |
| 41 #include "execution.h" | 42 #include "execution.h" |
| 42 #include "full-codegen.h" | 43 #include "full-codegen.h" |
| 43 #include "hydrogen.h" | 44 #include "hydrogen.h" |
| 44 #include "isolate-inl.h" | 45 #include "isolate-inl.h" |
| 45 #include "log.h" | 46 #include "log.h" |
| (...skipping 2731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2777 stdout, "", modify_index, descriptor, descriptors, | 2778 stdout, "", modify_index, descriptor, descriptors, |
| 2778 old_descriptors->GetDetails(modify_index).type() == CONSTANT && | 2779 old_descriptors->GetDetails(modify_index).type() == CONSTANT && |
| 2779 store_mode == FORCE_FIELD, | 2780 store_mode == FORCE_FIELD, |
| 2780 old_representation, updated_representation); | 2781 old_representation, updated_representation); |
| 2781 } | 2782 } |
| 2782 | 2783 |
| 2783 // Add missing transitions. | 2784 // Add missing transitions. |
| 2784 Handle<Map> new_map = split_map; | 2785 Handle<Map> new_map = split_map; |
| 2785 for (; descriptor < descriptors; descriptor++) { | 2786 for (; descriptor < descriptors; descriptor++) { |
| 2786 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors); | 2787 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors); |
| 2787 new_map->set_migration_target(true); | |
| 2788 } | 2788 } |
| 2789 | 2789 |
| 2790 new_map->set_owns_descriptors(true); | 2790 new_map->set_owns_descriptors(true); |
| 2791 return new_map; | 2791 return new_map; |
| 2792 } | 2792 } |
| 2793 | 2793 |
| 2794 | 2794 |
| 2795 // Generalize the representation of all FIELD descriptors. | 2795 // Generalize the representation of all FIELD descriptors. |
| 2796 Handle<Map> Map::GeneralizeAllFieldRepresentations( | 2796 Handle<Map> Map::GeneralizeAllFieldRepresentations( |
| 2797 Handle<Map> map, | 2797 Handle<Map> map, |
| (...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3868 } | 3868 } |
| 3869 | 3869 |
| 3870 | 3870 |
| 3871 void JSObject::MigrateInstance(Handle<JSObject> object) { | 3871 void JSObject::MigrateInstance(Handle<JSObject> object) { |
| 3872 // Converting any field to the most specific type will cause the | 3872 // Converting any field to the most specific type will cause the |
| 3873 // GeneralizeFieldRepresentation algorithm to create the most general existing | 3873 // GeneralizeFieldRepresentation algorithm to create the most general existing |
| 3874 // transition that matches the object. This achieves what is needed. | 3874 // transition that matches the object. This achieves what is needed. |
| 3875 Handle<Map> original_map(object->map()); | 3875 Handle<Map> original_map(object->map()); |
| 3876 GeneralizeFieldRepresentation( | 3876 GeneralizeFieldRepresentation( |
| 3877 object, 0, Representation::None(), ALLOW_AS_CONSTANT); | 3877 object, 0, Representation::None(), ALLOW_AS_CONSTANT); |
| 3878 object->map()->set_migration_target(true); |
| 3878 if (FLAG_trace_migration) { | 3879 if (FLAG_trace_migration) { |
| 3879 object->PrintInstanceMigration(stdout, *original_map, object->map()); | 3880 object->PrintInstanceMigration(stdout, *original_map, object->map()); |
| 3880 } | 3881 } |
| 3881 } | 3882 } |
| 3882 | 3883 |
| 3883 | 3884 |
| 3884 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { | 3885 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { |
| 3885 Map* new_map = object->map()->CurrentMapForDeprecated(); | 3886 Map* new_map = object->map()->CurrentMapForDeprecated(); |
| 3886 if (new_map == NULL) return Handle<Object>(); | 3887 if (new_map == NULL) return Handle<Object>(); |
| 3887 Handle<Map> original_map(object->map()); | 3888 Handle<Map> original_map(object->map()); |
| (...skipping 1760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5648 } else if (object->map()->CanHaveMoreTransitions()) { | 5649 } else if (object->map()->CanHaveMoreTransitions()) { |
| 5649 new_map = Map::CopyForObserved(handle(object->map())); | 5650 new_map = Map::CopyForObserved(handle(object->map())); |
| 5650 } else { | 5651 } else { |
| 5651 new_map = Map::Copy(handle(object->map())); | 5652 new_map = Map::Copy(handle(object->map())); |
| 5652 new_map->set_is_observed(); | 5653 new_map->set_is_observed(); |
| 5653 } | 5654 } |
| 5654 object->set_map(*new_map); | 5655 object->set_map(*new_map); |
| 5655 } | 5656 } |
| 5656 | 5657 |
| 5657 | 5658 |
| 5658 Handle<JSObject> JSObject::Copy(Handle<JSObject> object, | |
| 5659 Handle<AllocationSite> site) { | |
| 5660 Isolate* isolate = object->GetIsolate(); | |
| 5661 CALL_HEAP_FUNCTION(isolate, | |
| 5662 isolate->heap()->CopyJSObject(*object, *site), JSObject); | |
| 5663 } | |
| 5664 | |
| 5665 | |
| 5666 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { | 5659 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { |
| 5667 Isolate* isolate = object->GetIsolate(); | 5660 Isolate* isolate = object->GetIsolate(); |
| 5668 CALL_HEAP_FUNCTION(isolate, | 5661 CALL_HEAP_FUNCTION(isolate, |
| 5669 isolate->heap()->CopyJSObject(*object), JSObject); | 5662 isolate->heap()->CopyJSObject(*object), JSObject); |
| 5670 } | 5663 } |
| 5671 | 5664 |
| 5672 | 5665 |
| 5666 template<class ContextObject> |
| 5673 class JSObjectWalkVisitor { | 5667 class JSObjectWalkVisitor { |
| 5674 public: | 5668 public: |
| 5675 explicit JSObjectWalkVisitor(AllocationSiteContext* site_context) : | 5669 JSObjectWalkVisitor(ContextObject* site_context, bool copying, |
| 5676 site_context_(site_context) {} | 5670 JSObject::DeepCopyHints hints) |
| 5677 virtual ~JSObjectWalkVisitor() {} | 5671 : site_context_(site_context), |
| 5678 | 5672 copying_(copying), |
| 5679 Handle<JSObject> Visit(Handle<JSObject> object) { | 5673 hints_(hints) {} |
| 5680 return StructureWalk(object); | 5674 |
| 5681 } | 5675 Handle<JSObject> StructureWalk(Handle<JSObject> object); |
| 5682 | |
| 5683 virtual bool is_copying() = 0; | |
| 5684 | 5676 |
| 5685 protected: | 5677 protected: |
| 5686 Handle<JSObject> StructureWalk(Handle<JSObject> object); | 5678 inline Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object, |
| 5687 | 5679 Handle<JSObject> value) { |
| 5688 // The returned handle will be used for the object in all subsequent usages. | 5680 Handle<AllocationSite> current_site = site_context()->EnterNewScope(); |
| 5689 // This allows VisitObject to make a copy of the object if desired. | 5681 Handle<JSObject> copy_of_value = StructureWalk(value); |
| 5690 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) = 0; | 5682 site_context()->ExitScope(current_site, value); |
| 5691 virtual Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object, | 5683 return copy_of_value; |
| 5692 Handle<JSObject> value) = 0; | 5684 } |
| 5693 | 5685 |
| 5694 AllocationSiteContext* site_context() { return site_context_; } | 5686 inline ContextObject* site_context() { return site_context_; } |
| 5687 inline Isolate* isolate() { return site_context()->isolate(); } |
| 5688 |
| 5689 inline bool copying() const { return copying_; } |
| 5695 | 5690 |
| 5696 private: | 5691 private: |
| 5697 AllocationSiteContext* site_context_; | 5692 ContextObject* site_context_; |
| 5693 const bool copying_; |
| 5694 const JSObject::DeepCopyHints hints_; |
| 5698 }; | 5695 }; |
| 5699 | 5696 |
| 5700 | 5697 |
| 5701 class JSObjectCopyVisitor: public JSObjectWalkVisitor { | 5698 template <class ContextObject> |
| 5702 public: | 5699 Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk( |
| 5703 explicit JSObjectCopyVisitor(AllocationSiteContext* site_context) | 5700 Handle<JSObject> object) { |
| 5704 : JSObjectWalkVisitor(site_context) {} | 5701 Isolate* isolate = this->isolate(); |
| 5705 | 5702 bool copying = this->copying(); |
| 5706 virtual bool is_copying() V8_OVERRIDE { return true; } | 5703 bool shallow = hints_ == JSObject::kObjectIsShallowArray; |
| 5707 | 5704 |
| 5708 // The returned handle will be used for the object in all | 5705 if (!shallow) { |
| 5709 // subsequent usages. This allows VisitObject to make a copy | 5706 StackLimitCheck check(isolate); |
| 5710 // of the object if desired. | 5707 |
| 5711 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE { | 5708 if (check.HasOverflowed()) { |
| 5712 // Only create a memento if | 5709 isolate->StackOverflow(); |
| 5713 // 1) we have a JSArray, and | 5710 return Handle<JSObject>::null(); |
| 5714 // 2) the elements kind is palatable | 5711 } |
| 5715 // 3) allow_mementos is true | 5712 } |
| 5716 Handle<JSObject> copy; | 5713 |
| 5714 if (object->map()->is_deprecated()) { |
| 5715 JSObject::MigrateInstance(object); |
| 5716 } |
| 5717 |
| 5718 Handle<JSObject> copy; |
| 5719 if (copying) { |
| 5720 Handle<AllocationSite> site_to_pass; |
| 5717 if (site_context()->activated() && | 5721 if (site_context()->activated() && |
| 5718 AllocationSite::CanTrack(object->map()->instance_type()) && | 5722 AllocationSite::CanTrack(object->map()->instance_type()) && |
| 5719 AllocationSite::GetMode(object->GetElementsKind()) == | 5723 AllocationSite::GetMode(object->GetElementsKind()) == |
| 5720 TRACK_ALLOCATION_SITE) { | 5724 TRACK_ALLOCATION_SITE) { |
| 5721 copy = JSObject::Copy(object, site_context()->current()); | 5725 site_to_pass = site_context()->current(); |
| 5726 } |
| 5727 CALL_AND_RETRY_OR_DIE(isolate, |
| 5728 isolate->heap()->CopyJSObject(*object, |
| 5729 site_to_pass.is_null() ? NULL : *site_to_pass), |
| 5730 { copy = Handle<JSObject>(JSObject::cast(__object__), |
| 5731 isolate); |
| 5732 break; |
| 5733 }, |
| 5734 return Handle<JSObject>()); |
| 5735 } else { |
| 5736 copy = object; |
| 5737 } |
| 5738 |
| 5739 ASSERT(copying || copy.is_identical_to(object)); |
| 5740 |
| 5741 ElementsKind kind = copy->GetElementsKind(); |
| 5742 if (copying && IsFastSmiOrObjectElementsKind(kind) && |
| 5743 FixedArray::cast(copy->elements())->map() == |
| 5744 isolate->heap()->fixed_cow_array_map()) { |
| 5745 isolate->counters()->cow_arrays_created_runtime()->Increment(); |
| 5746 } |
| 5747 |
| 5748 if (!shallow) { |
| 5749 HandleScope scope(isolate); |
| 5750 |
| 5751 // Deep copy local properties. |
| 5752 if (copy->HasFastProperties()) { |
| 5753 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); |
| 5754 int limit = copy->map()->NumberOfOwnDescriptors(); |
| 5755 for (int i = 0; i < limit; i++) { |
| 5756 PropertyDetails details = descriptors->GetDetails(i); |
| 5757 if (details.type() != FIELD) continue; |
| 5758 int index = descriptors->GetFieldIndex(i); |
| 5759 Handle<Object> value(object->RawFastPropertyAt(index), isolate); |
| 5760 if (value->IsJSObject()) { |
| 5761 value = VisitElementOrProperty(copy, Handle<JSObject>::cast(value)); |
| 5762 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>()); |
| 5763 } else { |
| 5764 Representation representation = details.representation(); |
| 5765 value = NewStorageFor(isolate, value, representation); |
| 5766 } |
| 5767 if (copying) { |
| 5768 copy->FastPropertyAtPut(index, *value); |
| 5769 } |
| 5770 } |
| 5722 } else { | 5771 } else { |
| 5723 copy = JSObject::Copy(object); | 5772 Handle<FixedArray> names = |
| 5724 } | 5773 isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties()); |
| 5725 | 5774 copy->GetLocalPropertyNames(*names, 0); |
| 5726 return copy; | 5775 for (int i = 0; i < names->length(); i++) { |
| 5727 } | 5776 ASSERT(names->get(i)->IsString()); |
| 5728 | 5777 Handle<String> key_string(String::cast(names->get(i))); |
| 5729 virtual Handle<JSObject> VisitElementOrProperty( | 5778 PropertyAttributes attributes = |
| 5730 Handle<JSObject> object, | 5779 copy->GetLocalPropertyAttribute(*key_string); |
| 5731 Handle<JSObject> value) V8_OVERRIDE { | 5780 // Only deep copy fields from the object literal expression. |
| 5732 Handle<AllocationSite> current_site = site_context()->EnterNewScope(); | 5781 // In particular, don't try to copy the length attribute of |
| 5733 Handle<JSObject> copy_of_value = StructureWalk(value); | 5782 // an array. |
| 5734 site_context()->ExitScope(current_site, value); | 5783 if (attributes != NONE) continue; |
| 5735 return copy_of_value; | 5784 Handle<Object> value( |
| 5736 } | 5785 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), |
| 5737 }; | 5786 isolate); |
| 5738 | 5787 if (value->IsJSObject()) { |
| 5739 | 5788 Handle<JSObject> result = VisitElementOrProperty( |
| 5740 class JSObjectCreateAllocationSitesVisitor: public JSObjectWalkVisitor { | 5789 copy, Handle<JSObject>::cast(value)); |
| 5741 public: | 5790 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
| 5742 explicit JSObjectCreateAllocationSitesVisitor( | 5791 if (copying) { |
| 5743 AllocationSiteContext* site_context) | 5792 // Creating object copy for literals. No strict mode needed. |
| 5744 : JSObjectWalkVisitor(site_context) {} | 5793 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty( |
| 5745 | 5794 copy, key_string, result, NONE, kNonStrictMode)); |
| 5746 virtual bool is_copying() V8_OVERRIDE { return false; } | 5795 } |
| 5747 | 5796 } |
| 5748 // The returned handle will be used for the object in all | 5797 } |
| 5749 // subsequent usages. This allows VisitObject to make a copy | 5798 } |
| 5750 // of the object if desired. | 5799 |
| 5751 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE { | 5800 // Deep copy local elements. |
| 5752 return object; | 5801 // Pixel elements cannot be created using an object literal. |
| 5753 } | 5802 ASSERT(!copy->HasExternalArrayElements()); |
| 5754 | 5803 switch (kind) { |
| 5755 virtual Handle<JSObject> VisitElementOrProperty( | 5804 case FAST_SMI_ELEMENTS: |
| 5756 Handle<JSObject> object, | 5805 case FAST_ELEMENTS: |
| 5757 Handle<JSObject> value) V8_OVERRIDE { | 5806 case FAST_HOLEY_SMI_ELEMENTS: |
| 5758 Handle<AllocationSite> current_site = site_context()->EnterNewScope(); | 5807 case FAST_HOLEY_ELEMENTS: { |
| 5759 value = StructureWalk(value); | 5808 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); |
| 5760 site_context()->ExitScope(current_site, value); | 5809 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { |
| 5761 return value; | |
| 5762 } | |
| 5763 }; | |
| 5764 | |
| 5765 | |
| 5766 Handle<JSObject> JSObjectWalkVisitor::StructureWalk(Handle<JSObject> object) { | |
| 5767 bool copying = is_copying(); | |
| 5768 Isolate* isolate = object->GetIsolate(); | |
| 5769 StackLimitCheck check(isolate); | |
| 5770 if (check.HasOverflowed()) { | |
| 5771 isolate->StackOverflow(); | |
| 5772 return Handle<JSObject>::null(); | |
| 5773 } | |
| 5774 | |
| 5775 if (object->map()->is_deprecated()) { | |
| 5776 JSObject::MigrateInstance(object); | |
| 5777 } | |
| 5778 | |
| 5779 Handle<JSObject> copy = VisitObject(object); | |
| 5780 ASSERT(copying || copy.is_identical_to(object)); | |
| 5781 | |
| 5782 HandleScope scope(isolate); | |
| 5783 | |
| 5784 // Deep copy local properties. | |
| 5785 if (copy->HasFastProperties()) { | |
| 5786 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); | |
| 5787 int limit = copy->map()->NumberOfOwnDescriptors(); | |
| 5788 for (int i = 0; i < limit; i++) { | |
| 5789 PropertyDetails details = descriptors->GetDetails(i); | |
| 5790 if (details.type() != FIELD) continue; | |
| 5791 int index = descriptors->GetFieldIndex(i); | |
| 5792 Handle<Object> value(object->RawFastPropertyAt(index), isolate); | |
| 5793 if (value->IsJSObject()) { | |
| 5794 value = VisitElementOrProperty(copy, Handle<JSObject>::cast(value)); | |
| 5795 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>()); | |
| 5796 } else { | |
| 5797 Representation representation = details.representation(); | |
| 5798 value = NewStorageFor(isolate, value, representation); | |
| 5799 } | |
| 5800 if (copying) { | |
| 5801 copy->FastPropertyAtPut(index, *value); | |
| 5802 } | |
| 5803 } | |
| 5804 } else { | |
| 5805 Handle<FixedArray> names = | |
| 5806 isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties()); | |
| 5807 copy->GetLocalPropertyNames(*names, 0); | |
| 5808 for (int i = 0; i < names->length(); i++) { | |
| 5809 ASSERT(names->get(i)->IsString()); | |
| 5810 Handle<String> key_string(String::cast(names->get(i))); | |
| 5811 PropertyAttributes attributes = | |
| 5812 copy->GetLocalPropertyAttribute(*key_string); | |
| 5813 // Only deep copy fields from the object literal expression. | |
| 5814 // In particular, don't try to copy the length attribute of | |
| 5815 // an array. | |
| 5816 if (attributes != NONE) continue; | |
| 5817 Handle<Object> value( | |
| 5818 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), | |
| 5819 isolate); | |
| 5820 if (value->IsJSObject()) { | |
| 5821 Handle<JSObject> result = VisitElementOrProperty( | |
| 5822 copy, Handle<JSObject>::cast(value)); | |
| 5823 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | |
| 5824 if (copying) { | |
| 5825 // Creating object copy for literals. No strict mode needed. | |
| 5826 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty( | |
| 5827 copy, key_string, result, NONE, kNonStrictMode)); | |
| 5828 } | |
| 5829 } | |
| 5830 } | |
| 5831 } | |
| 5832 | |
| 5833 // Deep copy local elements. | |
| 5834 // Pixel elements cannot be created using an object literal. | |
| 5835 ASSERT(!copy->HasExternalArrayElements()); | |
| 5836 switch (copy->GetElementsKind()) { | |
| 5837 case FAST_SMI_ELEMENTS: | |
| 5838 case FAST_ELEMENTS: | |
| 5839 case FAST_HOLEY_SMI_ELEMENTS: | |
| 5840 case FAST_HOLEY_ELEMENTS: { | |
| 5841 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); | |
| 5842 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { | |
| 5843 if (copying) { | |
| 5844 isolate->counters()->cow_arrays_created_runtime()->Increment(); | |
| 5845 } | |
| 5846 #ifdef DEBUG | 5810 #ifdef DEBUG |
| 5847 for (int i = 0; i < elements->length(); i++) { | 5811 for (int i = 0; i < elements->length(); i++) { |
| 5848 ASSERT(!elements->get(i)->IsJSObject()); | 5812 ASSERT(!elements->get(i)->IsJSObject()); |
| 5849 } | 5813 } |
| 5850 #endif | 5814 #endif |
| 5851 } else { | 5815 } else { |
| 5852 for (int i = 0; i < elements->length(); i++) { | 5816 for (int i = 0; i < elements->length(); i++) { |
| 5853 Handle<Object> value(elements->get(i), isolate); | 5817 Handle<Object> value(elements->get(i), isolate); |
| 5854 ASSERT(value->IsSmi() || | 5818 ASSERT(value->IsSmi() || |
| 5855 value->IsTheHole() || | 5819 value->IsTheHole() || |
| 5856 (IsFastObjectElementsKind(copy->GetElementsKind()))); | 5820 (IsFastObjectElementsKind(copy->GetElementsKind()))); |
| 5857 if (value->IsJSObject()) { | 5821 if (value->IsJSObject()) { |
| 5858 Handle<JSObject> result = VisitElementOrProperty( | 5822 Handle<JSObject> result = VisitElementOrProperty( |
| 5859 copy, Handle<JSObject>::cast(value)); | 5823 copy, Handle<JSObject>::cast(value)); |
| 5860 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | 5824 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
| 5861 if (copying) { | 5825 if (copying) { |
| 5862 elements->set(i, *result); | 5826 elements->set(i, *result); |
| 5827 } |
| 5863 } | 5828 } |
| 5864 } | 5829 } |
| 5865 } | 5830 } |
| 5866 } | 5831 break; |
| 5867 break; | 5832 } |
| 5868 } | 5833 case DICTIONARY_ELEMENTS: { |
| 5869 case DICTIONARY_ELEMENTS: { | 5834 Handle<SeededNumberDictionary> element_dictionary( |
| 5870 Handle<SeededNumberDictionary> element_dictionary( | 5835 copy->element_dictionary()); |
| 5871 copy->element_dictionary()); | 5836 int capacity = element_dictionary->Capacity(); |
| 5872 int capacity = element_dictionary->Capacity(); | 5837 for (int i = 0; i < capacity; i++) { |
| 5873 for (int i = 0; i < capacity; i++) { | 5838 Object* k = element_dictionary->KeyAt(i); |
| 5874 Object* k = element_dictionary->KeyAt(i); | 5839 if (element_dictionary->IsKey(k)) { |
| 5875 if (element_dictionary->IsKey(k)) { | 5840 Handle<Object> value(element_dictionary->ValueAt(i), isolate); |
| 5876 Handle<Object> value(element_dictionary->ValueAt(i), isolate); | 5841 if (value->IsJSObject()) { |
| 5877 if (value->IsJSObject()) { | 5842 Handle<JSObject> result = VisitElementOrProperty( |
| 5878 Handle<JSObject> result = VisitElementOrProperty( | 5843 copy, Handle<JSObject>::cast(value)); |
| 5879 copy, Handle<JSObject>::cast(value)); | 5844 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
| 5880 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | 5845 if (copying) { |
| 5881 if (copying) { | 5846 element_dictionary->ValueAtPut(i, *result); |
| 5882 element_dictionary->ValueAtPut(i, *result); | 5847 } |
| 5883 } | 5848 } |
| 5884 } | 5849 } |
| 5885 } | 5850 } |
| 5886 } | 5851 break; |
| 5887 break; | 5852 } |
| 5888 } | 5853 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 5889 case NON_STRICT_ARGUMENTS_ELEMENTS: | 5854 UNIMPLEMENTED(); |
| 5890 UNIMPLEMENTED(); | 5855 break; |
| 5891 break; | 5856 case EXTERNAL_PIXEL_ELEMENTS: |
| 5892 case EXTERNAL_PIXEL_ELEMENTS: | 5857 case EXTERNAL_BYTE_ELEMENTS: |
| 5893 case EXTERNAL_BYTE_ELEMENTS: | 5858 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 5894 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 5859 case EXTERNAL_SHORT_ELEMENTS: |
| 5895 case EXTERNAL_SHORT_ELEMENTS: | 5860 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 5896 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 5861 case EXTERNAL_INT_ELEMENTS: |
| 5897 case EXTERNAL_INT_ELEMENTS: | 5862 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 5898 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 5863 case EXTERNAL_FLOAT_ELEMENTS: |
| 5899 case EXTERNAL_FLOAT_ELEMENTS: | 5864 case EXTERNAL_DOUBLE_ELEMENTS: |
| 5900 case EXTERNAL_DOUBLE_ELEMENTS: | 5865 case FAST_DOUBLE_ELEMENTS: |
| 5901 case FAST_DOUBLE_ELEMENTS: | 5866 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 5902 case FAST_HOLEY_DOUBLE_ELEMENTS: | 5867 // No contained objects, nothing to do. |
| 5903 // No contained objects, nothing to do. | 5868 break; |
| 5904 break; | 5869 } |
| 5905 } | 5870 } |
| 5871 |
| 5906 return copy; | 5872 return copy; |
| 5907 } | 5873 } |
| 5908 | 5874 |
| 5909 | 5875 |
| 5910 Handle<JSObject> JSObject::DeepWalk(Handle<JSObject> object, | 5876 Handle<JSObject> JSObject::DeepWalk( |
| 5911 AllocationSiteContext* site_context) { | 5877 Handle<JSObject> object, |
| 5912 JSObjectCreateAllocationSitesVisitor v(site_context); | 5878 AllocationSiteCreationContext* site_context) { |
| 5913 Handle<JSObject> result = v.Visit(object); | 5879 JSObjectWalkVisitor<AllocationSiteCreationContext> v(site_context, false, |
| 5914 ASSERT(!v.is_copying() && | 5880 kNoHints); |
| 5915 (result.is_null() || result.is_identical_to(object))); | 5881 Handle<JSObject> result = v.StructureWalk(object); |
| 5882 ASSERT(result.is_null() || result.is_identical_to(object)); |
| 5916 return result; | 5883 return result; |
| 5917 } | 5884 } |
| 5918 | 5885 |
| 5919 | 5886 |
| 5920 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object, | 5887 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object, |
| 5921 AllocationSiteContext* site_context) { | 5888 AllocationSiteUsageContext* site_context, |
| 5922 JSObjectCopyVisitor v(site_context); | 5889 DeepCopyHints hints) { |
| 5923 Handle<JSObject> copy = v.Visit(object); | 5890 JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context, true, hints); |
| 5924 ASSERT(v.is_copying() && !copy.is_identical_to(object)); | 5891 Handle<JSObject> copy = v.StructureWalk(object); |
| 5892 ASSERT(!copy.is_identical_to(object)); |
| 5925 return copy; | 5893 return copy; |
| 5926 } | 5894 } |
| 5927 | 5895 |
| 5928 | 5896 |
| 5929 // Tests for the fast common case for property enumeration: | 5897 // Tests for the fast common case for property enumeration: |
| 5930 // - This object and all prototypes has an enum cache (which means that | 5898 // - This object and all prototypes has an enum cache (which means that |
| 5931 // it is no proxy, has no interceptors and needs no access checks). | 5899 // it is no proxy, has no interceptors and needs no access checks). |
| 5932 // - This object has no elements. | 5900 // - This object has no elements. |
| 5933 // - No prototype has enumerable properties/elements. | 5901 // - No prototype has enumerable properties/elements. |
| 5934 bool JSReceiver::IsSimpleEnum() { | 5902 bool JSReceiver::IsSimpleEnum() { |
| (...skipping 4459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10394 Address p = rinfo->target_reference(); | 10362 Address p = rinfo->target_reference(); |
| 10395 VisitExternalReference(&p); | 10363 VisitExternalReference(&p); |
| 10396 } | 10364 } |
| 10397 | 10365 |
| 10398 | 10366 |
| 10399 void Code::InvalidateRelocation() { | 10367 void Code::InvalidateRelocation() { |
| 10400 set_relocation_info(GetHeap()->empty_byte_array()); | 10368 set_relocation_info(GetHeap()->empty_byte_array()); |
| 10401 } | 10369 } |
| 10402 | 10370 |
| 10403 | 10371 |
| 10372 void Code::InvalidateEmbeddedObjects() { |
| 10373 Object* undefined = GetHeap()->undefined_value(); |
| 10374 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
| 10375 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) { |
| 10376 RelocInfo::Mode mode = it.rinfo()->rmode(); |
| 10377 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
| 10378 it.rinfo()->set_target_object(undefined, SKIP_WRITE_BARRIER); |
| 10379 } |
| 10380 } |
| 10381 } |
| 10382 |
| 10383 |
| 10404 void Code::Relocate(intptr_t delta) { | 10384 void Code::Relocate(intptr_t delta) { |
| 10405 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { | 10385 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { |
| 10406 it.rinfo()->apply(delta); | 10386 it.rinfo()->apply(delta); |
| 10407 } | 10387 } |
| 10408 CPU::FlushICache(instruction_start(), instruction_size()); | 10388 CPU::FlushICache(instruction_start(), instruction_size()); |
| 10409 } | 10389 } |
| 10410 | 10390 |
| 10411 | 10391 |
| 10412 void Code::CopyFrom(const CodeDesc& desc) { | 10392 void Code::CopyFrom(const CodeDesc& desc) { |
| 10413 ASSERT(Marking::Color(this) == Marking::WHITE_OBJECT); | 10393 ASSERT(Marking::Color(this) == Marking::WHITE_OBJECT); |
| (...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11128 if (name != NULL) { | 11108 if (name != NULL) { |
| 11129 PrintF(out, "%s\n", name); | 11109 PrintF(out, "%s\n", name); |
| 11130 } else { | 11110 } else { |
| 11131 PrintF(out, "%d\n", extra); | 11111 PrintF(out, "%d\n", extra); |
| 11132 } | 11112 } |
| 11133 } | 11113 } |
| 11134 | 11114 |
| 11135 | 11115 |
| 11136 void Code::Disassemble(const char* name, FILE* out) { | 11116 void Code::Disassemble(const char* name, FILE* out) { |
| 11137 PrintF(out, "kind = %s\n", Kind2String(kind())); | 11117 PrintF(out, "kind = %s\n", Kind2String(kind())); |
| 11118 if (has_major_key()) { |
| 11119 PrintF(out, "major_key = %s\n", |
| 11120 CodeStub::MajorName(CodeStub::GetMajorKey(this), true)); |
| 11121 } |
| 11138 if (is_inline_cache_stub()) { | 11122 if (is_inline_cache_stub()) { |
| 11139 PrintF(out, "ic_state = %s\n", ICState2String(ic_state())); | 11123 PrintF(out, "ic_state = %s\n", ICState2String(ic_state())); |
| 11140 PrintExtraICState(out, kind(), needs_extended_extra_ic_state(kind()) ? | 11124 PrintExtraICState(out, kind(), needs_extended_extra_ic_state(kind()) ? |
| 11141 extended_extra_ic_state() : extra_ic_state()); | 11125 extended_extra_ic_state() : extra_ic_state()); |
| 11142 if (ic_state() == MONOMORPHIC) { | 11126 if (ic_state() == MONOMORPHIC) { |
| 11143 PrintF(out, "type = %s\n", StubType2String(type())); | 11127 PrintF(out, "type = %s\n", StubType2String(type())); |
| 11144 } | 11128 } |
| 11145 if (is_call_stub() || is_keyed_call_stub()) { | 11129 if (is_call_stub() || is_keyed_call_stub()) { |
| 11146 PrintF(out, "argc = %d\n", arguments_count()); | 11130 PrintF(out, "argc = %d\n", arguments_count()); |
| 11147 } | 11131 } |
| (...skipping 5520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16668 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16652 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16669 static const char* error_messages_[] = { | 16653 static const char* error_messages_[] = { |
| 16670 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16654 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16671 }; | 16655 }; |
| 16672 #undef ERROR_MESSAGES_TEXTS | 16656 #undef ERROR_MESSAGES_TEXTS |
| 16673 return error_messages_[reason]; | 16657 return error_messages_[reason]; |
| 16674 } | 16658 } |
| 16675 | 16659 |
| 16676 | 16660 |
| 16677 } } // namespace v8::internal | 16661 } } // namespace v8::internal |
| OLD | NEW |