| 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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 if (IsBoolean()) return IsTrue(); | 113 if (IsBoolean()) return IsTrue(); |
| 114 if (IsSmi()) return Smi::cast(this)->value() != 0; | 114 if (IsSmi()) return Smi::cast(this)->value() != 0; |
| 115 if (IsUndefined() || IsNull()) return false; | 115 if (IsUndefined() || IsNull()) return false; |
| 116 if (IsUndetectableObject()) return false; // Undetectable object is false. | 116 if (IsUndetectableObject()) return false; // Undetectable object is false. |
| 117 if (IsString()) return String::cast(this)->length() != 0; | 117 if (IsString()) return String::cast(this)->length() != 0; |
| 118 if (IsHeapNumber()) return HeapNumber::cast(this)->HeapNumberBooleanValue(); | 118 if (IsHeapNumber()) return HeapNumber::cast(this)->HeapNumberBooleanValue(); |
| 119 return true; | 119 return true; |
| 120 } | 120 } |
| 121 | 121 |
| 122 | 122 |
| 123 bool Object::IsCallable() { |
| 124 Object* fun = this; |
| 125 while (fun->IsJSFunctionProxy()) { |
| 126 fun = JSFunctionProxy::cast(fun)->call_trap(); |
| 127 } |
| 128 return fun->IsJSFunction() || |
| 129 (fun->IsHeapObject() && |
| 130 HeapObject::cast(fun)->map()->has_instance_call_handler()); |
| 131 } |
| 132 |
| 133 |
| 123 void Object::Lookup(Name* name, LookupResult* result) { | 134 void Object::Lookup(Name* name, LookupResult* result) { |
| 124 Object* holder = NULL; | 135 Object* holder = NULL; |
| 125 if (IsJSReceiver()) { | 136 if (IsJSReceiver()) { |
| 126 holder = this; | 137 holder = this; |
| 127 } else { | 138 } else { |
| 128 Context* native_context = result->isolate()->context()->native_context(); | 139 Context* native_context = result->isolate()->context()->native_context(); |
| 129 if (IsNumber()) { | 140 if (IsNumber()) { |
| 130 holder = native_context->number_function()->instance_prototype(); | 141 holder = native_context->number_function()->instance_prototype(); |
| 131 } else if (IsString()) { | 142 } else if (IsString()) { |
| 132 holder = native_context->string_function()->instance_prototype(); | 143 holder = native_context->string_function()->instance_prototype(); |
| (...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1665 break; | 1676 break; |
| 1666 case EXTERNAL_DOUBLE_ARRAY_TYPE: | 1677 case EXTERNAL_DOUBLE_ARRAY_TYPE: |
| 1667 accumulator->Add("<ExternalDoubleArray[%u]>", | 1678 accumulator->Add("<ExternalDoubleArray[%u]>", |
| 1668 ExternalDoubleArray::cast(this)->length()); | 1679 ExternalDoubleArray::cast(this)->length()); |
| 1669 break; | 1680 break; |
| 1670 case SHARED_FUNCTION_INFO_TYPE: { | 1681 case SHARED_FUNCTION_INFO_TYPE: { |
| 1671 SharedFunctionInfo* shared = SharedFunctionInfo::cast(this); | 1682 SharedFunctionInfo* shared = SharedFunctionInfo::cast(this); |
| 1672 SmartArrayPointer<char> debug_name = | 1683 SmartArrayPointer<char> debug_name = |
| 1673 shared->DebugName()->ToCString(); | 1684 shared->DebugName()->ToCString(); |
| 1674 if (debug_name[0] != 0) { | 1685 if (debug_name[0] != 0) { |
| 1675 accumulator->Add("<SharedFunctionInfo %s>", *debug_name); | 1686 accumulator->Add("<SharedFunctionInfo %s>", debug_name.get()); |
| 1676 } else { | 1687 } else { |
| 1677 accumulator->Add("<SharedFunctionInfo>"); | 1688 accumulator->Add("<SharedFunctionInfo>"); |
| 1678 } | 1689 } |
| 1679 break; | 1690 break; |
| 1680 } | 1691 } |
| 1681 case JS_MESSAGE_OBJECT_TYPE: | 1692 case JS_MESSAGE_OBJECT_TYPE: |
| 1682 accumulator->Add("<JSMessageObject>"); | 1693 accumulator->Add("<JSMessageObject>"); |
| 1683 break; | 1694 break; |
| 1684 #define MAKE_STRUCT_CASE(NAME, Name, name) \ | 1695 #define MAKE_STRUCT_CASE(NAME, Name, name) \ |
| 1685 case NAME##_TYPE: \ | 1696 case NAME##_TYPE: \ |
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2211 | 2222 |
| 2212 Execution::Call(isolate, | 2223 Execution::Call(isolate, |
| 2213 Handle<JSFunction>(isolate->observers_notify_change()), | 2224 Handle<JSFunction>(isolate->observers_notify_change()), |
| 2214 isolate->factory()->undefined_value(), | 2225 isolate->factory()->undefined_value(), |
| 2215 argc, args, | 2226 argc, args, |
| 2216 &threw); | 2227 &threw); |
| 2217 ASSERT(!threw); | 2228 ASSERT(!threw); |
| 2218 } | 2229 } |
| 2219 | 2230 |
| 2220 | 2231 |
| 2221 void JSObject::DeliverChangeRecords(Isolate* isolate) { | |
| 2222 ASSERT(isolate->observer_delivery_pending()); | |
| 2223 bool threw = false; | |
| 2224 Execution::Call( | |
| 2225 isolate, | |
| 2226 isolate->observers_deliver_changes(), | |
| 2227 isolate->factory()->undefined_value(), | |
| 2228 0, | |
| 2229 NULL, | |
| 2230 &threw); | |
| 2231 ASSERT(!threw); | |
| 2232 isolate->set_observer_delivery_pending(false); | |
| 2233 } | |
| 2234 | |
| 2235 | |
| 2236 Handle<Object> JSObject::SetPropertyPostInterceptor( | 2232 Handle<Object> JSObject::SetPropertyPostInterceptor( |
| 2237 Handle<JSObject> object, | 2233 Handle<JSObject> object, |
| 2238 Handle<Name> name, | 2234 Handle<Name> name, |
| 2239 Handle<Object> value, | 2235 Handle<Object> value, |
| 2240 PropertyAttributes attributes, | 2236 PropertyAttributes attributes, |
| 2241 StrictModeFlag strict_mode) { | 2237 StrictModeFlag strict_mode) { |
| 2242 // Check local property, ignore interceptor. | 2238 // Check local property, ignore interceptor. |
| 2243 LookupResult result(object->GetIsolate()); | 2239 LookupResult result(object->GetIsolate()); |
| 2244 object->LocalLookupRealNamedProperty(*name, &result); | 2240 object->LocalLookupRealNamedProperty(*name, &result); |
| 2245 if (!result.IsFound()) { | 2241 if (!result.IsFound()) { |
| (...skipping 3403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5649 } else if (object->map()->CanHaveMoreTransitions()) { | 5645 } else if (object->map()->CanHaveMoreTransitions()) { |
| 5650 new_map = Map::CopyForObserved(handle(object->map())); | 5646 new_map = Map::CopyForObserved(handle(object->map())); |
| 5651 } else { | 5647 } else { |
| 5652 new_map = Map::Copy(handle(object->map())); | 5648 new_map = Map::Copy(handle(object->map())); |
| 5653 new_map->set_is_observed(); | 5649 new_map->set_is_observed(); |
| 5654 } | 5650 } |
| 5655 object->set_map(*new_map); | 5651 object->set_map(*new_map); |
| 5656 } | 5652 } |
| 5657 | 5653 |
| 5658 | 5654 |
| 5659 Handle<JSObject> JSObject::Copy(Handle<JSObject> object, | |
| 5660 Handle<AllocationSite> site) { | |
| 5661 Isolate* isolate = object->GetIsolate(); | |
| 5662 CALL_HEAP_FUNCTION(isolate, | |
| 5663 isolate->heap()->CopyJSObject(*object, *site), JSObject); | |
| 5664 } | |
| 5665 | |
| 5666 | |
| 5667 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { | 5655 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { |
| 5668 Isolate* isolate = object->GetIsolate(); | 5656 Isolate* isolate = object->GetIsolate(); |
| 5669 CALL_HEAP_FUNCTION(isolate, | 5657 CALL_HEAP_FUNCTION(isolate, |
| 5670 isolate->heap()->CopyJSObject(*object), JSObject); | 5658 isolate->heap()->CopyJSObject(*object), JSObject); |
| 5671 } | 5659 } |
| 5672 | 5660 |
| 5673 | 5661 |
| 5662 template<class ContextObject> |
| 5674 class JSObjectWalkVisitor { | 5663 class JSObjectWalkVisitor { |
| 5675 public: | 5664 public: |
| 5676 explicit JSObjectWalkVisitor(AllocationSiteContext* site_context) : | 5665 JSObjectWalkVisitor(ContextObject* site_context, bool copying, |
| 5677 site_context_(site_context) {} | 5666 JSObject::DeepCopyHints hints) |
| 5678 virtual ~JSObjectWalkVisitor() {} | 5667 : site_context_(site_context), |
| 5679 | 5668 copying_(copying), |
| 5680 Handle<JSObject> Visit(Handle<JSObject> object) { | 5669 hints_(hints) {} |
| 5681 return StructureWalk(object); | 5670 |
| 5682 } | 5671 Handle<JSObject> StructureWalk(Handle<JSObject> object); |
| 5683 | |
| 5684 virtual bool is_copying() = 0; | |
| 5685 | 5672 |
| 5686 protected: | 5673 protected: |
| 5687 Handle<JSObject> StructureWalk(Handle<JSObject> object); | 5674 inline Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object, |
| 5688 | 5675 Handle<JSObject> value) { |
| 5689 // The returned handle will be used for the object in all subsequent usages. | |
| 5690 // This allows VisitObject to make a copy of the object if desired. | |
| 5691 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) = 0; | |
| 5692 virtual Handle<JSObject> VisitElementOrProperty(Handle<JSObject> object, | |
| 5693 Handle<JSObject> value) = 0; | |
| 5694 | |
| 5695 AllocationSiteContext* site_context() { return site_context_; } | |
| 5696 | |
| 5697 private: | |
| 5698 AllocationSiteContext* site_context_; | |
| 5699 }; | |
| 5700 | |
| 5701 | |
| 5702 class JSObjectCopyVisitor: public JSObjectWalkVisitor { | |
| 5703 public: | |
| 5704 explicit JSObjectCopyVisitor(AllocationSiteContext* site_context) | |
| 5705 : JSObjectWalkVisitor(site_context) {} | |
| 5706 | |
| 5707 virtual bool is_copying() V8_OVERRIDE { return true; } | |
| 5708 | |
| 5709 // The returned handle will be used for the object in all | |
| 5710 // subsequent usages. This allows VisitObject to make a copy | |
| 5711 // of the object if desired. | |
| 5712 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE { | |
| 5713 // Only create a memento if | |
| 5714 // 1) we have a JSArray, and | |
| 5715 // 2) the elements kind is palatable | |
| 5716 // 3) allow_mementos is true | |
| 5717 Handle<JSObject> copy; | |
| 5718 if (site_context()->activated() && | |
| 5719 AllocationSite::CanTrack(object->map()->instance_type()) && | |
| 5720 AllocationSite::GetMode(object->GetElementsKind()) == | |
| 5721 TRACK_ALLOCATION_SITE) { | |
| 5722 copy = JSObject::Copy(object, site_context()->current()); | |
| 5723 } else { | |
| 5724 copy = JSObject::Copy(object); | |
| 5725 } | |
| 5726 | |
| 5727 return copy; | |
| 5728 } | |
| 5729 | |
| 5730 virtual Handle<JSObject> VisitElementOrProperty( | |
| 5731 Handle<JSObject> object, | |
| 5732 Handle<JSObject> value) V8_OVERRIDE { | |
| 5733 Handle<AllocationSite> current_site = site_context()->EnterNewScope(); | 5676 Handle<AllocationSite> current_site = site_context()->EnterNewScope(); |
| 5734 Handle<JSObject> copy_of_value = StructureWalk(value); | 5677 Handle<JSObject> copy_of_value = StructureWalk(value); |
| 5735 site_context()->ExitScope(current_site, value); | 5678 site_context()->ExitScope(current_site, value); |
| 5736 return copy_of_value; | 5679 return copy_of_value; |
| 5737 } | 5680 } |
| 5681 |
| 5682 inline ContextObject* site_context() { return site_context_; } |
| 5683 inline Isolate* isolate() { return site_context()->isolate(); } |
| 5684 |
| 5685 inline bool copying() const { return copying_; } |
| 5686 |
| 5687 private: |
| 5688 ContextObject* site_context_; |
| 5689 const bool copying_; |
| 5690 const JSObject::DeepCopyHints hints_; |
| 5738 }; | 5691 }; |
| 5739 | 5692 |
| 5740 | 5693 |
| 5741 class JSObjectCreateAllocationSitesVisitor: public JSObjectWalkVisitor { | 5694 template <class ContextObject> |
| 5742 public: | 5695 Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk( |
| 5743 explicit JSObjectCreateAllocationSitesVisitor( | 5696 Handle<JSObject> object) { |
| 5744 AllocationSiteContext* site_context) | 5697 Isolate* isolate = this->isolate(); |
| 5745 : JSObjectWalkVisitor(site_context) {} | 5698 bool copying = this->copying(); |
| 5746 | 5699 bool shallow = hints_ == JSObject::kObjectIsShallowArray; |
| 5747 virtual bool is_copying() V8_OVERRIDE { return false; } | 5700 |
| 5748 | 5701 if (!shallow) { |
| 5749 // The returned handle will be used for the object in all | 5702 StackLimitCheck check(isolate); |
| 5750 // subsequent usages. This allows VisitObject to make a copy | 5703 |
| 5751 // of the object if desired. | 5704 if (check.HasOverflowed()) { |
| 5752 virtual Handle<JSObject> VisitObject(Handle<JSObject> object) V8_OVERRIDE { | 5705 isolate->StackOverflow(); |
| 5753 return object; | 5706 return Handle<JSObject>::null(); |
| 5754 } | 5707 } |
| 5755 | |
| 5756 virtual Handle<JSObject> VisitElementOrProperty( | |
| 5757 Handle<JSObject> object, | |
| 5758 Handle<JSObject> value) V8_OVERRIDE { | |
| 5759 Handle<AllocationSite> current_site = site_context()->EnterNewScope(); | |
| 5760 value = StructureWalk(value); | |
| 5761 site_context()->ExitScope(current_site, value); | |
| 5762 return value; | |
| 5763 } | |
| 5764 }; | |
| 5765 | |
| 5766 | |
| 5767 Handle<JSObject> JSObjectWalkVisitor::StructureWalk(Handle<JSObject> object) { | |
| 5768 bool copying = is_copying(); | |
| 5769 Isolate* isolate = object->GetIsolate(); | |
| 5770 StackLimitCheck check(isolate); | |
| 5771 if (check.HasOverflowed()) { | |
| 5772 isolate->StackOverflow(); | |
| 5773 return Handle<JSObject>::null(); | |
| 5774 } | 5708 } |
| 5775 | 5709 |
| 5776 if (object->map()->is_deprecated()) { | 5710 if (object->map()->is_deprecated()) { |
| 5777 JSObject::MigrateInstance(object); | 5711 JSObject::MigrateInstance(object); |
| 5778 } | 5712 } |
| 5779 | 5713 |
| 5780 Handle<JSObject> copy = VisitObject(object); | 5714 Handle<JSObject> copy; |
| 5715 if (copying) { |
| 5716 Handle<AllocationSite> site_to_pass; |
| 5717 if (site_context()->ShouldCreateMemento(object)) { |
| 5718 site_to_pass = site_context()->current(); |
| 5719 } |
| 5720 CALL_AND_RETRY_OR_DIE(isolate, |
| 5721 isolate->heap()->CopyJSObject(*object, |
| 5722 site_to_pass.is_null() ? NULL : *site_to_pass), |
| 5723 { copy = Handle<JSObject>(JSObject::cast(__object__), |
| 5724 isolate); |
| 5725 break; |
| 5726 }, |
| 5727 return Handle<JSObject>()); |
| 5728 } else { |
| 5729 copy = object; |
| 5730 } |
| 5731 |
| 5781 ASSERT(copying || copy.is_identical_to(object)); | 5732 ASSERT(copying || copy.is_identical_to(object)); |
| 5782 | 5733 |
| 5783 HandleScope scope(isolate); | 5734 ElementsKind kind = copy->GetElementsKind(); |
| 5784 | 5735 if (copying && IsFastSmiOrObjectElementsKind(kind) && |
| 5785 // Deep copy local properties. | 5736 FixedArray::cast(copy->elements())->map() == |
| 5786 if (copy->HasFastProperties()) { | 5737 isolate->heap()->fixed_cow_array_map()) { |
| 5787 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); | 5738 isolate->counters()->cow_arrays_created_runtime()->Increment(); |
| 5788 int limit = copy->map()->NumberOfOwnDescriptors(); | 5739 } |
| 5789 for (int i = 0; i < limit; i++) { | 5740 |
| 5790 PropertyDetails details = descriptors->GetDetails(i); | 5741 if (!shallow) { |
| 5791 if (details.type() != FIELD) continue; | 5742 HandleScope scope(isolate); |
| 5792 int index = descriptors->GetFieldIndex(i); | 5743 |
| 5793 Handle<Object> value(object->RawFastPropertyAt(index), isolate); | 5744 // Deep copy local properties. |
| 5794 if (value->IsJSObject()) { | 5745 if (copy->HasFastProperties()) { |
| 5795 value = VisitElementOrProperty(copy, Handle<JSObject>::cast(value)); | 5746 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); |
| 5796 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>()); | 5747 int limit = copy->map()->NumberOfOwnDescriptors(); |
| 5797 } else { | 5748 for (int i = 0; i < limit; i++) { |
| 5798 Representation representation = details.representation(); | 5749 PropertyDetails details = descriptors->GetDetails(i); |
| 5799 value = NewStorageFor(isolate, value, representation); | 5750 if (details.type() != FIELD) continue; |
| 5800 } | 5751 int index = descriptors->GetFieldIndex(i); |
| 5801 if (copying) { | 5752 Handle<Object> value(object->RawFastPropertyAt(index), isolate); |
| 5802 copy->FastPropertyAtPut(index, *value); | 5753 if (value->IsJSObject()) { |
| 5803 } | 5754 value = VisitElementOrProperty(copy, Handle<JSObject>::cast(value)); |
| 5804 } | 5755 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>()); |
| 5805 } else { | 5756 } else { |
| 5806 Handle<FixedArray> names = | 5757 Representation representation = details.representation(); |
| 5807 isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties()); | 5758 value = NewStorageFor(isolate, value, representation); |
| 5808 copy->GetLocalPropertyNames(*names, 0); | 5759 } |
| 5809 for (int i = 0; i < names->length(); i++) { | |
| 5810 ASSERT(names->get(i)->IsString()); | |
| 5811 Handle<String> key_string(String::cast(names->get(i))); | |
| 5812 PropertyAttributes attributes = | |
| 5813 copy->GetLocalPropertyAttribute(*key_string); | |
| 5814 // Only deep copy fields from the object literal expression. | |
| 5815 // In particular, don't try to copy the length attribute of | |
| 5816 // an array. | |
| 5817 if (attributes != NONE) continue; | |
| 5818 Handle<Object> value( | |
| 5819 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), | |
| 5820 isolate); | |
| 5821 if (value->IsJSObject()) { | |
| 5822 Handle<JSObject> result = VisitElementOrProperty( | |
| 5823 copy, Handle<JSObject>::cast(value)); | |
| 5824 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | |
| 5825 if (copying) { | 5760 if (copying) { |
| 5826 // Creating object copy for literals. No strict mode needed. | 5761 copy->FastPropertyAtPut(index, *value); |
| 5827 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty( | 5762 } |
| 5828 copy, key_string, result, NONE, kNonStrictMode)); | 5763 } |
| 5829 } | 5764 } else { |
| 5830 } | 5765 Handle<FixedArray> names = |
| 5831 } | 5766 isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties()); |
| 5832 } | 5767 copy->GetLocalPropertyNames(*names, 0); |
| 5833 | 5768 for (int i = 0; i < names->length(); i++) { |
| 5834 // Deep copy local elements. | 5769 ASSERT(names->get(i)->IsString()); |
| 5835 // Pixel elements cannot be created using an object literal. | 5770 Handle<String> key_string(String::cast(names->get(i))); |
| 5836 ASSERT(!copy->HasExternalArrayElements()); | 5771 PropertyAttributes attributes = |
| 5837 switch (copy->GetElementsKind()) { | 5772 copy->GetLocalPropertyAttribute(*key_string); |
| 5838 case FAST_SMI_ELEMENTS: | 5773 // Only deep copy fields from the object literal expression. |
| 5839 case FAST_ELEMENTS: | 5774 // In particular, don't try to copy the length attribute of |
| 5840 case FAST_HOLEY_SMI_ELEMENTS: | 5775 // an array. |
| 5841 case FAST_HOLEY_ELEMENTS: { | 5776 if (attributes != NONE) continue; |
| 5842 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); | 5777 Handle<Object> value( |
| 5843 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { | 5778 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), |
| 5844 if (copying) { | 5779 isolate); |
| 5845 isolate->counters()->cow_arrays_created_runtime()->Increment(); | 5780 if (value->IsJSObject()) { |
| 5846 } | 5781 Handle<JSObject> result = VisitElementOrProperty( |
| 5782 copy, Handle<JSObject>::cast(value)); |
| 5783 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
| 5784 if (copying) { |
| 5785 // Creating object copy for literals. No strict mode needed. |
| 5786 CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetProperty( |
| 5787 copy, key_string, result, NONE, kNonStrictMode)); |
| 5788 } |
| 5789 } |
| 5790 } |
| 5791 } |
| 5792 |
| 5793 // Deep copy local elements. |
| 5794 // Pixel elements cannot be created using an object literal. |
| 5795 ASSERT(!copy->HasExternalArrayElements()); |
| 5796 switch (kind) { |
| 5797 case FAST_SMI_ELEMENTS: |
| 5798 case FAST_ELEMENTS: |
| 5799 case FAST_HOLEY_SMI_ELEMENTS: |
| 5800 case FAST_HOLEY_ELEMENTS: { |
| 5801 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); |
| 5802 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { |
| 5847 #ifdef DEBUG | 5803 #ifdef DEBUG |
| 5848 for (int i = 0; i < elements->length(); i++) { | 5804 for (int i = 0; i < elements->length(); i++) { |
| 5849 ASSERT(!elements->get(i)->IsJSObject()); | 5805 ASSERT(!elements->get(i)->IsJSObject()); |
| 5850 } | 5806 } |
| 5851 #endif | 5807 #endif |
| 5852 } else { | 5808 } else { |
| 5853 for (int i = 0; i < elements->length(); i++) { | 5809 for (int i = 0; i < elements->length(); i++) { |
| 5854 Handle<Object> value(elements->get(i), isolate); | 5810 Handle<Object> value(elements->get(i), isolate); |
| 5855 ASSERT(value->IsSmi() || | 5811 ASSERT(value->IsSmi() || |
| 5856 value->IsTheHole() || | 5812 value->IsTheHole() || |
| 5857 (IsFastObjectElementsKind(copy->GetElementsKind()))); | 5813 (IsFastObjectElementsKind(copy->GetElementsKind()))); |
| 5858 if (value->IsJSObject()) { | 5814 if (value->IsJSObject()) { |
| 5859 Handle<JSObject> result = VisitElementOrProperty( | 5815 Handle<JSObject> result = VisitElementOrProperty( |
| 5860 copy, Handle<JSObject>::cast(value)); | 5816 copy, Handle<JSObject>::cast(value)); |
| 5861 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | 5817 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
| 5862 if (copying) { | 5818 if (copying) { |
| 5863 elements->set(i, *result); | 5819 elements->set(i, *result); |
| 5820 } |
| 5864 } | 5821 } |
| 5865 } | 5822 } |
| 5866 } | 5823 } |
| 5867 } | 5824 break; |
| 5868 break; | 5825 } |
| 5869 } | 5826 case DICTIONARY_ELEMENTS: { |
| 5870 case DICTIONARY_ELEMENTS: { | 5827 Handle<SeededNumberDictionary> element_dictionary( |
| 5871 Handle<SeededNumberDictionary> element_dictionary( | 5828 copy->element_dictionary()); |
| 5872 copy->element_dictionary()); | 5829 int capacity = element_dictionary->Capacity(); |
| 5873 int capacity = element_dictionary->Capacity(); | 5830 for (int i = 0; i < capacity; i++) { |
| 5874 for (int i = 0; i < capacity; i++) { | 5831 Object* k = element_dictionary->KeyAt(i); |
| 5875 Object* k = element_dictionary->KeyAt(i); | 5832 if (element_dictionary->IsKey(k)) { |
| 5876 if (element_dictionary->IsKey(k)) { | 5833 Handle<Object> value(element_dictionary->ValueAt(i), isolate); |
| 5877 Handle<Object> value(element_dictionary->ValueAt(i), isolate); | 5834 if (value->IsJSObject()) { |
| 5878 if (value->IsJSObject()) { | 5835 Handle<JSObject> result = VisitElementOrProperty( |
| 5879 Handle<JSObject> result = VisitElementOrProperty( | 5836 copy, Handle<JSObject>::cast(value)); |
| 5880 copy, Handle<JSObject>::cast(value)); | 5837 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
| 5881 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | 5838 if (copying) { |
| 5882 if (copying) { | 5839 element_dictionary->ValueAtPut(i, *result); |
| 5883 element_dictionary->ValueAtPut(i, *result); | 5840 } |
| 5884 } | 5841 } |
| 5885 } | 5842 } |
| 5886 } | 5843 } |
| 5887 } | 5844 break; |
| 5888 break; | 5845 } |
| 5889 } | 5846 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 5890 case NON_STRICT_ARGUMENTS_ELEMENTS: | 5847 UNIMPLEMENTED(); |
| 5891 UNIMPLEMENTED(); | 5848 break; |
| 5892 break; | 5849 case EXTERNAL_PIXEL_ELEMENTS: |
| 5893 case EXTERNAL_PIXEL_ELEMENTS: | 5850 case EXTERNAL_BYTE_ELEMENTS: |
| 5894 case EXTERNAL_BYTE_ELEMENTS: | 5851 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 5895 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 5852 case EXTERNAL_SHORT_ELEMENTS: |
| 5896 case EXTERNAL_SHORT_ELEMENTS: | 5853 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 5897 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 5854 case EXTERNAL_INT_ELEMENTS: |
| 5898 case EXTERNAL_INT_ELEMENTS: | 5855 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 5899 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 5856 case EXTERNAL_FLOAT_ELEMENTS: |
| 5900 case EXTERNAL_FLOAT_ELEMENTS: | 5857 case EXTERNAL_DOUBLE_ELEMENTS: |
| 5901 case EXTERNAL_DOUBLE_ELEMENTS: | 5858 case FAST_DOUBLE_ELEMENTS: |
| 5902 case FAST_DOUBLE_ELEMENTS: | 5859 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 5903 case FAST_HOLEY_DOUBLE_ELEMENTS: | 5860 // No contained objects, nothing to do. |
| 5904 // No contained objects, nothing to do. | 5861 break; |
| 5905 break; | 5862 } |
| 5906 } | 5863 } |
| 5864 |
| 5907 return copy; | 5865 return copy; |
| 5908 } | 5866 } |
| 5909 | 5867 |
| 5910 | 5868 |
| 5911 Handle<JSObject> JSObject::DeepWalk(Handle<JSObject> object, | 5869 Handle<JSObject> JSObject::DeepWalk( |
| 5912 AllocationSiteContext* site_context) { | 5870 Handle<JSObject> object, |
| 5913 JSObjectCreateAllocationSitesVisitor v(site_context); | 5871 AllocationSiteCreationContext* site_context) { |
| 5914 Handle<JSObject> result = v.Visit(object); | 5872 JSObjectWalkVisitor<AllocationSiteCreationContext> v(site_context, false, |
| 5915 ASSERT(!v.is_copying() && | 5873 kNoHints); |
| 5916 (result.is_null() || result.is_identical_to(object))); | 5874 Handle<JSObject> result = v.StructureWalk(object); |
| 5875 ASSERT(result.is_null() || result.is_identical_to(object)); |
| 5917 return result; | 5876 return result; |
| 5918 } | 5877 } |
| 5919 | 5878 |
| 5920 | 5879 |
| 5921 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object, | 5880 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object, |
| 5922 AllocationSiteContext* site_context) { | 5881 AllocationSiteUsageContext* site_context, |
| 5923 JSObjectCopyVisitor v(site_context); | 5882 DeepCopyHints hints) { |
| 5924 Handle<JSObject> copy = v.Visit(object); | 5883 JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context, true, hints); |
| 5925 ASSERT(v.is_copying() && !copy.is_identical_to(object)); | 5884 Handle<JSObject> copy = v.StructureWalk(object); |
| 5885 ASSERT(!copy.is_identical_to(object)); |
| 5926 return copy; | 5886 return copy; |
| 5927 } | 5887 } |
| 5928 | 5888 |
| 5929 | 5889 |
| 5930 // Tests for the fast common case for property enumeration: | 5890 // Tests for the fast common case for property enumeration: |
| 5931 // - This object and all prototypes has an enum cache (which means that | 5891 // - This object and all prototypes has an enum cache (which means that |
| 5932 // it is no proxy, has no interceptors and needs no access checks). | 5892 // it is no proxy, has no interceptors and needs no access checks). |
| 5933 // - This object has no elements. | 5893 // - This object has no elements. |
| 5934 // - No prototype has enumerable properties/elements. | 5894 // - No prototype has enumerable properties/elements. |
| 5935 bool JSReceiver::IsSimpleEnum() { | 5895 bool JSReceiver::IsSimpleEnum() { |
| (...skipping 3271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9207 | 9167 |
| 9208 | 9168 |
| 9209 if (new_length == 0) return heap->isolate()->factory()->empty_string(); | 9169 if (new_length == 0) return heap->isolate()->factory()->empty_string(); |
| 9210 return string; | 9170 return string; |
| 9211 } | 9171 } |
| 9212 | 9172 |
| 9213 | 9173 |
| 9214 AllocationMemento* AllocationMemento::FindForJSObject(JSObject* object, | 9174 AllocationMemento* AllocationMemento::FindForJSObject(JSObject* object, |
| 9215 bool in_GC) { | 9175 bool in_GC) { |
| 9216 // Currently, AllocationMemento objects are only allocated immediately | 9176 // Currently, AllocationMemento objects are only allocated immediately |
| 9217 // after JSArrays in NewSpace, and detecting whether a JSArray has one | 9177 // after JSArrays and some JSObjects in NewSpace. Detecting whether a |
| 9218 // involves carefully checking the object immediately after the JSArray | 9178 // memento is present involves carefully checking the object immediately |
| 9219 // (if there is one) to see if it's an AllocationMemento. | 9179 // after the current object (if there is one) to see if it's an |
| 9180 // AllocationMemento. |
| 9220 if (FLAG_track_allocation_sites && object->GetHeap()->InNewSpace(object)) { | 9181 if (FLAG_track_allocation_sites && object->GetHeap()->InNewSpace(object)) { |
| 9221 Address ptr_end = (reinterpret_cast<Address>(object) - kHeapObjectTag) + | 9182 Address ptr_end = (reinterpret_cast<Address>(object) - kHeapObjectTag) + |
| 9222 object->Size(); | 9183 object->Size(); |
| 9223 Address top; | 9184 Address top; |
| 9224 if (in_GC) { | 9185 if (in_GC) { |
| 9225 top = object->GetHeap()->new_space()->FromSpacePageHigh(); | 9186 top = object->GetHeap()->new_space()->FromSpacePageHigh(); |
| 9226 } else { | 9187 } else { |
| 9227 top = object->GetHeap()->NewSpaceTop(); | 9188 top = object->GetHeap()->NewSpaceTop(); |
| 9228 } | 9189 } |
| 9229 if ((ptr_end + AllocationMemento::kSize) <= top) { | 9190 if ((ptr_end + AllocationMemento::kSize) <= top) { |
| 9230 // There is room in newspace for allocation info. Do we have some? | 9191 // There is room in newspace for allocation info. Do we have some? |
| 9231 Map** possible_allocation_memento_map = | 9192 Map** possible_allocation_memento_map = |
| 9232 reinterpret_cast<Map**>(ptr_end); | 9193 reinterpret_cast<Map**>(ptr_end); |
| 9233 if (*possible_allocation_memento_map == | 9194 if (*possible_allocation_memento_map == |
| 9234 object->GetHeap()->allocation_memento_map()) { | 9195 object->GetHeap()->allocation_memento_map()) { |
| 9235 AllocationMemento* memento = AllocationMemento::cast( | 9196 AllocationMemento* memento = AllocationMemento::cast( |
| 9236 reinterpret_cast<Object*>(ptr_end + kHeapObjectTag)); | 9197 reinterpret_cast<Object*>(ptr_end + kHeapObjectTag)); |
| 9237 return memento; | 9198 if (memento->IsValid()) { |
| 9199 return memento; |
| 9200 } |
| 9238 } | 9201 } |
| 9239 } | 9202 } |
| 9240 } | 9203 } |
| 9241 return NULL; | 9204 return NULL; |
| 9242 } | 9205 } |
| 9243 | 9206 |
| 9244 | 9207 |
| 9245 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) { | 9208 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) { |
| 9246 // For array indexes mix the length into the hash as an array index could | 9209 // For array indexes mix the length into the hash as an array index could |
| 9247 // be zero. | 9210 // be zero. |
| (...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9943 } | 9906 } |
| 9944 | 9907 |
| 9945 | 9908 |
| 9946 void JSFunction::SetInstanceClassName(String* name) { | 9909 void JSFunction::SetInstanceClassName(String* name) { |
| 9947 shared()->set_instance_class_name(name); | 9910 shared()->set_instance_class_name(name); |
| 9948 } | 9911 } |
| 9949 | 9912 |
| 9950 | 9913 |
| 9951 void JSFunction::PrintName(FILE* out) { | 9914 void JSFunction::PrintName(FILE* out) { |
| 9952 SmartArrayPointer<char> name = shared()->DebugName()->ToCString(); | 9915 SmartArrayPointer<char> name = shared()->DebugName()->ToCString(); |
| 9953 PrintF(out, "%s", *name); | 9916 PrintF(out, "%s", name.get()); |
| 9954 } | 9917 } |
| 9955 | 9918 |
| 9956 | 9919 |
| 9957 Context* JSFunction::NativeContextFromLiterals(FixedArray* literals) { | 9920 Context* JSFunction::NativeContextFromLiterals(FixedArray* literals) { |
| 9958 return Context::cast(literals->get(JSFunction::kLiteralNativeContextIndex)); | 9921 return Context::cast(literals->get(JSFunction::kLiteralNativeContextIndex)); |
| 9959 } | 9922 } |
| 9960 | 9923 |
| 9961 | 9924 |
| 9962 // The filter is a pattern that matches function names in this way: | 9925 // The filter is a pattern that matches function names in this way: |
| 9963 // "*" all; the default | 9926 // "*" all; the default |
| (...skipping 2851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12815 } | 12778 } |
| 12816 | 12779 |
| 12817 | 12780 |
| 12818 void JSObject::TransitionElementsKind(Handle<JSObject> object, | 12781 void JSObject::TransitionElementsKind(Handle<JSObject> object, |
| 12819 ElementsKind to_kind) { | 12782 ElementsKind to_kind) { |
| 12820 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), | 12783 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), |
| 12821 object->TransitionElementsKind(to_kind)); | 12784 object->TransitionElementsKind(to_kind)); |
| 12822 } | 12785 } |
| 12823 | 12786 |
| 12824 | 12787 |
| 12788 const double AllocationSite::kPretenureRatio = 0.60; |
| 12789 |
| 12790 |
| 12825 bool AllocationSite::IsNestedSite() { | 12791 bool AllocationSite::IsNestedSite() { |
| 12826 ASSERT(FLAG_trace_track_allocation_sites); | 12792 ASSERT(FLAG_trace_track_allocation_sites); |
| 12827 Object* current = GetHeap()->allocation_sites_list(); | 12793 Object* current = GetHeap()->allocation_sites_list(); |
| 12828 while (current != NULL && current->IsAllocationSite()) { | 12794 while (current != NULL && current->IsAllocationSite()) { |
| 12829 AllocationSite* current_site = AllocationSite::cast(current); | 12795 AllocationSite* current_site = AllocationSite::cast(current); |
| 12830 if (current_site->nested_site() == this) { | 12796 if (current_site->nested_site() == this) { |
| 12831 return true; | 12797 return true; |
| 12832 } | 12798 } |
| 12833 current = current_site->weak_next(); | 12799 current = current_site->weak_next(); |
| 12834 } | 12800 } |
| (...skipping 3850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16685 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16651 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16686 static const char* error_messages_[] = { | 16652 static const char* error_messages_[] = { |
| 16687 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16653 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16688 }; | 16654 }; |
| 16689 #undef ERROR_MESSAGES_TEXTS | 16655 #undef ERROR_MESSAGES_TEXTS |
| 16690 return error_messages_[reason]; | 16656 return error_messages_[reason]; |
| 16691 } | 16657 } |
| 16692 | 16658 |
| 16693 | 16659 |
| 16694 } } // namespace v8::internal | 16660 } } // namespace v8::internal |
| OLD | NEW |