| 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 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 double num = HeapNumber::cast(this)->value(); | 197 double num = HeapNumber::cast(this)->value(); |
| 197 if (num >= 0 && FastUI2D(FastD2UI(num)) == num) { | 198 if (num >= 0 && FastUI2D(FastD2UI(num)) == num) { |
| 198 *value = FastD2UI(num); | 199 *value = FastD2UI(num); |
| 199 return true; | 200 return true; |
| 200 } | 201 } |
| 201 } | 202 } |
| 202 return false; | 203 return false; |
| 203 } | 204 } |
| 204 | 205 |
| 205 | 206 |
| 207 bool FunctionTemplateInfo::IsTemplateFor(Object* object) { |
| 208 if (!object->IsHeapObject()) return false; |
| 209 return IsTemplateFor(HeapObject::cast(object)->map()); |
| 210 } |
| 211 |
| 212 |
| 213 bool FunctionTemplateInfo::IsTemplateFor(Map* map) { |
| 214 // There is a constraint on the object; check. |
| 215 if (!map->IsJSObjectMap()) return false; |
| 216 // Fetch the constructor function of the object. |
| 217 Object* cons_obj = map->constructor(); |
| 218 if (!cons_obj->IsJSFunction()) return false; |
| 219 JSFunction* fun = JSFunction::cast(cons_obj); |
| 220 // Iterate through the chain of inheriting function templates to |
| 221 // see if the required one occurs. |
| 222 for (Object* type = fun->shared()->function_data(); |
| 223 type->IsFunctionTemplateInfo(); |
| 224 type = FunctionTemplateInfo::cast(type)->parent_template()) { |
| 225 if (type == this) return true; |
| 226 } |
| 227 // Didn't find the required type in the inheritance chain. |
| 228 return false; |
| 229 } |
| 230 |
| 231 |
| 206 template<typename To> | 232 template<typename To> |
| 207 static inline To* CheckedCast(void *from) { | 233 static inline To* CheckedCast(void *from) { |
| 208 uintptr_t temp = reinterpret_cast<uintptr_t>(from); | 234 uintptr_t temp = reinterpret_cast<uintptr_t>(from); |
| 209 ASSERT(temp % sizeof(To) == 0); | 235 ASSERT(temp % sizeof(To) == 0); |
| 210 return reinterpret_cast<To*>(temp); | 236 return reinterpret_cast<To*>(temp); |
| 211 } | 237 } |
| 212 | 238 |
| 213 | 239 |
| 214 static MaybeObject* PerformCompare(const BitmaskCompareDescriptor& descriptor, | 240 static MaybeObject* PerformCompare(const BitmaskCompareDescriptor& descriptor, |
| 215 char* ptr, | 241 char* ptr, |
| (...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1021 return context->symbol_function()->instance_prototype(); | 1047 return context->symbol_function()->instance_prototype(); |
| 1022 } | 1048 } |
| 1023 if (heap_object->IsBoolean()) { | 1049 if (heap_object->IsBoolean()) { |
| 1024 return context->boolean_function()->instance_prototype(); | 1050 return context->boolean_function()->instance_prototype(); |
| 1025 } else { | 1051 } else { |
| 1026 return isolate->heap()->null_value(); | 1052 return isolate->heap()->null_value(); |
| 1027 } | 1053 } |
| 1028 } | 1054 } |
| 1029 | 1055 |
| 1030 | 1056 |
| 1057 Map* Object::GetMarkerMap(Isolate* isolate) { |
| 1058 if (IsSmi()) return isolate->heap()->heap_number_map(); |
| 1059 return HeapObject::cast(this)->map(); |
| 1060 } |
| 1061 |
| 1062 |
| 1031 Object* Object::GetHash() { | 1063 Object* Object::GetHash() { |
| 1032 // The object is either a number, a name, an odd-ball, | 1064 // The object is either a number, a name, an odd-ball, |
| 1033 // a real JS object, or a Harmony proxy. | 1065 // a real JS object, or a Harmony proxy. |
| 1034 if (IsNumber()) { | 1066 if (IsNumber()) { |
| 1035 uint32_t hash = ComputeLongHash(double_to_uint64(Number())); | 1067 uint32_t hash = ComputeLongHash(double_to_uint64(Number())); |
| 1036 return Smi::FromInt(hash & Smi::kMaxValue); | 1068 return Smi::FromInt(hash & Smi::kMaxValue); |
| 1037 } | 1069 } |
| 1038 if (IsName()) { | 1070 if (IsName()) { |
| 1039 uint32_t hash = Name::cast(this)->Hash(); | 1071 uint32_t hash = Name::cast(this)->Hash(); |
| 1040 return Smi::FromInt(hash); | 1072 return Smi::FromInt(hash); |
| (...skipping 1083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2124 Handle<Object> args[1] = { name }; | 2156 Handle<Object> args[1] = { name }; |
| 2125 Handle<Object> error = isolate->factory()->NewTypeError( | 2157 Handle<Object> error = isolate->factory()->NewTypeError( |
| 2126 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); | 2158 "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); |
| 2127 isolate->Throw(*error); | 2159 isolate->Throw(*error); |
| 2128 return Handle<Object>(); | 2160 return Handle<Object>(); |
| 2129 } | 2161 } |
| 2130 } | 2162 } |
| 2131 | 2163 |
| 2132 if (object->HasFastProperties()) { | 2164 if (object->HasFastProperties()) { |
| 2133 // Ensure the descriptor array does not get too big. | 2165 // Ensure the descriptor array does not get too big. |
| 2134 if (object->map()->NumberOfOwnDescriptors() < | 2166 if (object->map()->NumberOfOwnDescriptors() <= kMaxNumberOfDescriptors) { |
| 2135 DescriptorArray::kMaxNumberOfDescriptors) { | |
| 2136 // TODO(verwaest): Support other constants. | 2167 // TODO(verwaest): Support other constants. |
| 2137 // if (mode == ALLOW_AS_CONSTANT && | 2168 // if (mode == ALLOW_AS_CONSTANT && |
| 2138 // !value->IsTheHole() && | 2169 // !value->IsTheHole() && |
| 2139 // !value->IsConsString()) { | 2170 // !value->IsConsString()) { |
| 2140 if (value->IsJSFunction()) { | 2171 if (value->IsJSFunction()) { |
| 2141 AddConstantProperty(object, name, value, attributes, transition_flag); | 2172 AddConstantProperty(object, name, value, attributes, transition_flag); |
| 2142 } else { | 2173 } else { |
| 2143 AddFastProperty(object, name, value, attributes, store_mode, | 2174 AddFastProperty(object, name, value, attributes, store_mode, |
| 2144 value_type, transition_flag); | 2175 value_type, transition_flag); |
| 2145 } | 2176 } |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2547 transitions->GetTarget(transition)->DeprecateTransitionTree(); | 2578 transitions->GetTarget(transition)->DeprecateTransitionTree(); |
| 2548 } | 2579 } |
| 2549 } | 2580 } |
| 2550 | 2581 |
| 2551 // Don't overwrite the empty descriptor array. | 2582 // Don't overwrite the empty descriptor array. |
| 2552 if (NumberOfOwnDescriptors() == 0) return; | 2583 if (NumberOfOwnDescriptors() == 0) return; |
| 2553 | 2584 |
| 2554 DescriptorArray* to_replace = instance_descriptors(); | 2585 DescriptorArray* to_replace = instance_descriptors(); |
| 2555 Map* current = this; | 2586 Map* current = this; |
| 2556 while (current->instance_descriptors() == to_replace) { | 2587 while (current->instance_descriptors() == to_replace) { |
| 2557 current->SetEnumLength(Map::kInvalidEnumCache); | 2588 current->SetEnumLength(kInvalidEnumCacheSentinel); |
| 2558 current->set_instance_descriptors(new_descriptors); | 2589 current->set_instance_descriptors(new_descriptors); |
| 2559 Object* next = current->GetBackPointer(); | 2590 Object* next = current->GetBackPointer(); |
| 2560 if (next->IsUndefined()) break; | 2591 if (next->IsUndefined()) break; |
| 2561 current = Map::cast(next); | 2592 current = Map::cast(next); |
| 2562 } | 2593 } |
| 2563 | 2594 |
| 2564 set_owns_descriptors(false); | 2595 set_owns_descriptors(false); |
| 2565 } | 2596 } |
| 2566 | 2597 |
| 2567 | 2598 |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2747 stdout, "", modify_index, descriptor, descriptors, | 2778 stdout, "", modify_index, descriptor, descriptors, |
| 2748 old_descriptors->GetDetails(modify_index).type() == CONSTANT && | 2779 old_descriptors->GetDetails(modify_index).type() == CONSTANT && |
| 2749 store_mode == FORCE_FIELD, | 2780 store_mode == FORCE_FIELD, |
| 2750 old_representation, updated_representation); | 2781 old_representation, updated_representation); |
| 2751 } | 2782 } |
| 2752 | 2783 |
| 2753 // Add missing transitions. | 2784 // Add missing transitions. |
| 2754 Handle<Map> new_map = split_map; | 2785 Handle<Map> new_map = split_map; |
| 2755 for (; descriptor < descriptors; descriptor++) { | 2786 for (; descriptor < descriptors; descriptor++) { |
| 2756 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors); | 2787 new_map = Map::CopyInstallDescriptors(new_map, descriptor, new_descriptors); |
| 2757 new_map->set_migration_target(true); | |
| 2758 } | 2788 } |
| 2759 | 2789 |
| 2760 new_map->set_owns_descriptors(true); | 2790 new_map->set_owns_descriptors(true); |
| 2761 return new_map; | 2791 return new_map; |
| 2762 } | 2792 } |
| 2763 | 2793 |
| 2764 | 2794 |
| 2765 // Generalize the representation of all FIELD descriptors. | 2795 // Generalize the representation of all FIELD descriptors. |
| 2766 Handle<Map> Map::GeneralizeAllFieldRepresentations( | 2796 Handle<Map> Map::GeneralizeAllFieldRepresentations( |
| 2767 Handle<Map> map, | 2797 Handle<Map> map, |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2959 bool has_pending_exception; | 2989 bool has_pending_exception; |
| 2960 Handle<Object> argv[] = { value }; | 2990 Handle<Object> argv[] = { value }; |
| 2961 Execution::Call( | 2991 Execution::Call( |
| 2962 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception); | 2992 isolate, setter, object, ARRAY_SIZE(argv), argv, &has_pending_exception); |
| 2963 // Check for pending exception and return the result. | 2993 // Check for pending exception and return the result. |
| 2964 if (has_pending_exception) return Handle<Object>(); | 2994 if (has_pending_exception) return Handle<Object>(); |
| 2965 return value; | 2995 return value; |
| 2966 } | 2996 } |
| 2967 | 2997 |
| 2968 | 2998 |
| 2969 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( | 2999 Handle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( |
| 3000 Handle<JSObject> object, |
| 2970 uint32_t index, | 3001 uint32_t index, |
| 2971 Object* value, | 3002 Handle<Object> value, |
| 2972 bool* found, | 3003 bool* found, |
| 2973 StrictModeFlag strict_mode) { | 3004 StrictModeFlag strict_mode) { |
| 2974 Heap* heap = GetHeap(); | 3005 Isolate *isolate = object->GetIsolate(); |
| 2975 for (Object* pt = GetPrototype(); | 3006 for (Handle<Object> proto = handle(object->GetPrototype(), isolate); |
| 2976 pt != heap->null_value(); | 3007 !proto->IsNull(); |
| 2977 pt = pt->GetPrototype(GetIsolate())) { | 3008 proto = handle(proto->GetPrototype(isolate), isolate)) { |
| 2978 if (pt->IsJSProxy()) { | 3009 if (proto->IsJSProxy()) { |
| 2979 Isolate* isolate = GetIsolate(); | 3010 return JSProxy::SetPropertyViaPrototypesWithHandler( |
| 2980 HandleScope scope(isolate); | 3011 Handle<JSProxy>::cast(proto), |
| 2981 Handle<JSProxy> proxy(JSProxy::cast(pt)); | 3012 object, |
| 2982 Handle<JSObject> self(this, isolate); | 3013 isolate->factory()->Uint32ToString(index), // name |
| 2983 Handle<String> name = isolate->factory()->Uint32ToString(index); | 3014 value, |
| 2984 Handle<Object> value_handle(value, isolate); | 3015 NONE, |
| 2985 Handle<Object> result = JSProxy::SetPropertyViaPrototypesWithHandler( | 3016 strict_mode, |
| 2986 proxy, self, name, value_handle, NONE, strict_mode, found); | 3017 found); |
| 2987 RETURN_IF_EMPTY_HANDLE(isolate, result); | |
| 2988 return *result; | |
| 2989 } | 3018 } |
| 2990 if (!JSObject::cast(pt)->HasDictionaryElements()) { | 3019 Handle<JSObject> js_proto = Handle<JSObject>::cast(proto); |
| 3020 if (!js_proto->HasDictionaryElements()) { |
| 2991 continue; | 3021 continue; |
| 2992 } | 3022 } |
| 2993 SeededNumberDictionary* dictionary = | 3023 Handle<SeededNumberDictionary> dictionary(js_proto->element_dictionary()); |
| 2994 JSObject::cast(pt)->element_dictionary(); | |
| 2995 int entry = dictionary->FindEntry(index); | 3024 int entry = dictionary->FindEntry(index); |
| 2996 if (entry != SeededNumberDictionary::kNotFound) { | 3025 if (entry != SeededNumberDictionary::kNotFound) { |
| 2997 PropertyDetails details = dictionary->DetailsAt(entry); | 3026 PropertyDetails details = dictionary->DetailsAt(entry); |
| 2998 if (details.type() == CALLBACKS) { | 3027 if (details.type() == CALLBACKS) { |
| 2999 *found = true; | 3028 *found = true; |
| 3000 Isolate* isolate = GetIsolate(); | |
| 3001 HandleScope scope(isolate); | |
| 3002 Handle<JSObject> self(this, isolate); | |
| 3003 Handle<Object> structure(dictionary->ValueAt(entry), isolate); | 3029 Handle<Object> structure(dictionary->ValueAt(entry), isolate); |
| 3004 Handle<Object> value_handle(value, isolate); | 3030 return SetElementWithCallback(object, structure, index, value, js_proto, |
| 3005 Handle<JSObject> holder(JSObject::cast(pt)); | 3031 strict_mode); |
| 3006 Handle<Object> result = SetElementWithCallback( | |
| 3007 self, structure, index, value_handle, holder, strict_mode); | |
| 3008 RETURN_IF_EMPTY_HANDLE(isolate, result); | |
| 3009 return *result; | |
| 3010 } | 3032 } |
| 3011 } | 3033 } |
| 3012 } | 3034 } |
| 3013 *found = false; | 3035 *found = false; |
| 3014 return heap->the_hole_value(); | 3036 return isolate->factory()->the_hole_value(); |
| 3015 } | 3037 } |
| 3016 | 3038 |
| 3017 | 3039 |
| 3018 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, | 3040 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, |
| 3019 Handle<Name> name, | 3041 Handle<Name> name, |
| 3020 Handle<Object> value, | 3042 Handle<Object> value, |
| 3021 PropertyAttributes attributes, | 3043 PropertyAttributes attributes, |
| 3022 StrictModeFlag strict_mode, | 3044 StrictModeFlag strict_mode, |
| 3023 bool* done) { | 3045 bool* done) { |
| 3024 Isolate* isolate = object->GetIsolate(); | 3046 Isolate* isolate = object->GetIsolate(); |
| (...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3846 } | 3868 } |
| 3847 | 3869 |
| 3848 | 3870 |
| 3849 void JSObject::MigrateInstance(Handle<JSObject> object) { | 3871 void JSObject::MigrateInstance(Handle<JSObject> object) { |
| 3850 // Converting any field to the most specific type will cause the | 3872 // Converting any field to the most specific type will cause the |
| 3851 // GeneralizeFieldRepresentation algorithm to create the most general existing | 3873 // GeneralizeFieldRepresentation algorithm to create the most general existing |
| 3852 // transition that matches the object. This achieves what is needed. | 3874 // transition that matches the object. This achieves what is needed. |
| 3853 Handle<Map> original_map(object->map()); | 3875 Handle<Map> original_map(object->map()); |
| 3854 GeneralizeFieldRepresentation( | 3876 GeneralizeFieldRepresentation( |
| 3855 object, 0, Representation::None(), ALLOW_AS_CONSTANT); | 3877 object, 0, Representation::None(), ALLOW_AS_CONSTANT); |
| 3878 object->map()->set_migration_target(true); |
| 3856 if (FLAG_trace_migration) { | 3879 if (FLAG_trace_migration) { |
| 3857 object->PrintInstanceMigration(stdout, *original_map, object->map()); | 3880 object->PrintInstanceMigration(stdout, *original_map, object->map()); |
| 3858 } | 3881 } |
| 3859 } | 3882 } |
| 3860 | 3883 |
| 3861 | 3884 |
| 3862 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { | 3885 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) { |
| 3863 Map* new_map = object->map()->CurrentMapForDeprecated(); | 3886 Map* new_map = object->map()->CurrentMapForDeprecated(); |
| 3864 if (new_map == NULL) return Handle<Object>(); | 3887 if (new_map == NULL) return Handle<Object>(); |
| 3865 Handle<Map> original_map(object->map()); | 3888 Handle<Map> original_map(object->map()); |
| (...skipping 1741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5607 return object; | 5630 return object; |
| 5608 } | 5631 } |
| 5609 | 5632 |
| 5610 | 5633 |
| 5611 void JSObject::SetObserved(Handle<JSObject> object) { | 5634 void JSObject::SetObserved(Handle<JSObject> object) { |
| 5612 Isolate* isolate = object->GetIsolate(); | 5635 Isolate* isolate = object->GetIsolate(); |
| 5613 | 5636 |
| 5614 if (object->map()->is_observed()) | 5637 if (object->map()->is_observed()) |
| 5615 return; | 5638 return; |
| 5616 | 5639 |
| 5617 if (!object->HasExternalArrayElements()) { | |
| 5618 // Go to dictionary mode, so that we don't skip map checks. | |
| 5619 NormalizeElements(object); | |
| 5620 ASSERT(!object->HasFastElements()); | |
| 5621 } | |
| 5622 | |
| 5623 LookupResult result(isolate); | 5640 LookupResult result(isolate); |
| 5624 object->map()->LookupTransition(*object, | 5641 object->map()->LookupTransition(*object, |
| 5625 isolate->heap()->observed_symbol(), | 5642 isolate->heap()->observed_symbol(), |
| 5626 &result); | 5643 &result); |
| 5627 | 5644 |
| 5628 Handle<Map> new_map; | 5645 Handle<Map> new_map; |
| 5629 if (result.IsTransition()) { | 5646 if (result.IsTransition()) { |
| 5630 new_map = handle(result.GetTransitionTarget()); | 5647 new_map = handle(result.GetTransitionTarget()); |
| 5631 ASSERT(new_map->is_observed()); | 5648 ASSERT(new_map->is_observed()); |
| 5632 } else if (object->map()->CanHaveMoreTransitions()) { | 5649 } else if (object->map()->CanHaveMoreTransitions()) { |
| 5633 new_map = Map::CopyForObserved(handle(object->map())); | 5650 new_map = Map::CopyForObserved(handle(object->map())); |
| 5634 } else { | 5651 } else { |
| 5635 new_map = Map::Copy(handle(object->map())); | 5652 new_map = Map::Copy(handle(object->map())); |
| 5636 new_map->set_is_observed(true); | 5653 new_map->set_is_observed(); |
| 5637 } | 5654 } |
| 5638 object->set_map(*new_map); | 5655 object->set_map(*new_map); |
| 5639 } | 5656 } |
| 5640 | 5657 |
| 5641 | 5658 |
| 5642 Handle<JSObject> JSObject::Copy(Handle<JSObject> object, | 5659 Handle<JSObject> JSObject::Copy(Handle<JSObject> object, |
| 5643 Handle<AllocationSite> site) { | 5660 Handle<AllocationSite> site) { |
| 5644 Isolate* isolate = object->GetIsolate(); | 5661 Isolate* isolate = object->GetIsolate(); |
| 5645 CALL_HEAP_FUNCTION(isolate, | 5662 CALL_HEAP_FUNCTION(isolate, |
| 5646 isolate->heap()->CopyJSObject(*object, *site), JSObject); | 5663 isolate->heap()->CopyJSObject(*object, *site), JSObject); |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5916 // - This object has no elements. | 5933 // - This object has no elements. |
| 5917 // - No prototype has enumerable properties/elements. | 5934 // - No prototype has enumerable properties/elements. |
| 5918 bool JSReceiver::IsSimpleEnum() { | 5935 bool JSReceiver::IsSimpleEnum() { |
| 5919 Heap* heap = GetHeap(); | 5936 Heap* heap = GetHeap(); |
| 5920 for (Object* o = this; | 5937 for (Object* o = this; |
| 5921 o != heap->null_value(); | 5938 o != heap->null_value(); |
| 5922 o = JSObject::cast(o)->GetPrototype()) { | 5939 o = JSObject::cast(o)->GetPrototype()) { |
| 5923 if (!o->IsJSObject()) return false; | 5940 if (!o->IsJSObject()) return false; |
| 5924 JSObject* curr = JSObject::cast(o); | 5941 JSObject* curr = JSObject::cast(o); |
| 5925 int enum_length = curr->map()->EnumLength(); | 5942 int enum_length = curr->map()->EnumLength(); |
| 5926 if (enum_length == Map::kInvalidEnumCache) return false; | 5943 if (enum_length == kInvalidEnumCacheSentinel) return false; |
| 5927 ASSERT(!curr->HasNamedInterceptor()); | 5944 ASSERT(!curr->HasNamedInterceptor()); |
| 5928 ASSERT(!curr->HasIndexedInterceptor()); | 5945 ASSERT(!curr->HasIndexedInterceptor()); |
| 5929 ASSERT(!curr->IsAccessCheckNeeded()); | 5946 ASSERT(!curr->IsAccessCheckNeeded()); |
| 5930 if (curr->NumberOfEnumElements() > 0) return false; | 5947 if (curr->NumberOfEnumElements() > 0) return false; |
| 5931 if (curr != this && enum_length != 0) return false; | 5948 if (curr != this && enum_length != 0) return false; |
| 5932 } | 5949 } |
| 5933 return true; | 5950 return true; |
| 5934 } | 5951 } |
| 5935 | 5952 |
| 5936 | 5953 |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6170 Handle<Name> name, | 6187 Handle<Name> name, |
| 6171 Handle<Object> getter, | 6188 Handle<Object> getter, |
| 6172 Handle<Object> setter, | 6189 Handle<Object> setter, |
| 6173 PropertyAttributes attributes, | 6190 PropertyAttributes attributes, |
| 6174 v8::AccessControl access_control) { | 6191 v8::AccessControl access_control) { |
| 6175 // We could assert that the property is configurable here, but we would need | 6192 // We could assert that the property is configurable here, but we would need |
| 6176 // to do a lookup, which seems to be a bit of overkill. | 6193 // to do a lookup, which seems to be a bit of overkill. |
| 6177 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); | 6194 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); |
| 6178 if (object->HasFastProperties() && !only_attribute_changes && | 6195 if (object->HasFastProperties() && !only_attribute_changes && |
| 6179 access_control == v8::DEFAULT && | 6196 access_control == v8::DEFAULT && |
| 6180 (object->map()->NumberOfOwnDescriptors() < | 6197 (object->map()->NumberOfOwnDescriptors() <= kMaxNumberOfDescriptors)) { |
| 6181 DescriptorArray::kMaxNumberOfDescriptors)) { | |
| 6182 bool getterOk = getter->IsNull() || | 6198 bool getterOk = getter->IsNull() || |
| 6183 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes); | 6199 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes); |
| 6184 bool setterOk = !getterOk || setter->IsNull() || | 6200 bool setterOk = !getterOk || setter->IsNull() || |
| 6185 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes); | 6201 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes); |
| 6186 if (getterOk && setterOk) return; | 6202 if (getterOk && setterOk) return; |
| 6187 } | 6203 } |
| 6188 | 6204 |
| 6189 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); | 6205 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); |
| 6190 accessors->SetComponents(*getter, *setter); | 6206 accessors->SetComponents(*getter, *setter); |
| 6191 accessors->set_access_flags(access_control); | 6207 accessors->set_access_flags(access_control); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6249 Handle<Object> structure, | 6265 Handle<Object> structure, |
| 6250 PropertyAttributes attributes) { | 6266 PropertyAttributes attributes) { |
| 6251 Heap* heap = object->GetHeap(); | 6267 Heap* heap = object->GetHeap(); |
| 6252 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); | 6268 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); |
| 6253 | 6269 |
| 6254 // Normalize elements to make this operation simple. | 6270 // Normalize elements to make this operation simple. |
| 6255 bool had_dictionary_elements = object->HasDictionaryElements(); | 6271 bool had_dictionary_elements = object->HasDictionaryElements(); |
| 6256 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 6272 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
| 6257 ASSERT(object->HasDictionaryElements() || | 6273 ASSERT(object->HasDictionaryElements() || |
| 6258 object->HasDictionaryArgumentsElements()); | 6274 object->HasDictionaryArgumentsElements()); |
| 6259 | |
| 6260 // Update the dictionary with the new CALLBACKS property. | 6275 // Update the dictionary with the new CALLBACKS property. |
| 6261 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, | 6276 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, |
| 6262 details); | 6277 details); |
| 6263 dictionary->set_requires_slow_elements(); | 6278 dictionary->set_requires_slow_elements(); |
| 6264 | 6279 |
| 6265 // Update the dictionary backing store on the object. | 6280 // Update the dictionary backing store on the object. |
| 6266 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) { | 6281 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) { |
| 6267 // Also delete any parameter alias. | 6282 // Also delete any parameter alias. |
| 6268 // | 6283 // |
| 6269 // TODO(kmillikin): when deleting the last parameter alias we could | 6284 // TODO(kmillikin): when deleting the last parameter alias we could |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6689 GetHeap()->AllocateMap(instance_type(), instance_size); | 6704 GetHeap()->AllocateMap(instance_type(), instance_size); |
| 6690 if (!maybe_result->To(&result)) return maybe_result; | 6705 if (!maybe_result->To(&result)) return maybe_result; |
| 6691 | 6706 |
| 6692 result->set_prototype(prototype()); | 6707 result->set_prototype(prototype()); |
| 6693 result->set_constructor(constructor()); | 6708 result->set_constructor(constructor()); |
| 6694 result->set_bit_field(bit_field()); | 6709 result->set_bit_field(bit_field()); |
| 6695 result->set_bit_field2(bit_field2()); | 6710 result->set_bit_field2(bit_field2()); |
| 6696 int new_bit_field3 = bit_field3(); | 6711 int new_bit_field3 = bit_field3(); |
| 6697 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true); | 6712 new_bit_field3 = OwnsDescriptors::update(new_bit_field3, true); |
| 6698 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0); | 6713 new_bit_field3 = NumberOfOwnDescriptorsBits::update(new_bit_field3, 0); |
| 6699 new_bit_field3 = EnumLengthBits::update(new_bit_field3, kInvalidEnumCache); | 6714 new_bit_field3 = EnumLengthBits::update(new_bit_field3, |
| 6715 kInvalidEnumCacheSentinel); |
| 6700 new_bit_field3 = Deprecated::update(new_bit_field3, false); | 6716 new_bit_field3 = Deprecated::update(new_bit_field3, false); |
| 6701 new_bit_field3 = IsUnstable::update(new_bit_field3, false); | 6717 new_bit_field3 = IsUnstable::update(new_bit_field3, false); |
| 6702 result->set_bit_field3(new_bit_field3); | 6718 result->set_bit_field3(new_bit_field3); |
| 6703 return result; | 6719 return result; |
| 6704 } | 6720 } |
| 6705 | 6721 |
| 6706 | 6722 |
| 6707 Handle<Map> Map::CopyNormalized(Handle<Map> map, | 6723 Handle<Map> Map::CopyNormalized(Handle<Map> map, |
| 6708 PropertyNormalizationMode mode, | 6724 PropertyNormalizationMode mode, |
| 6709 NormalizedMapSharingMode sharing) { | 6725 NormalizedMapSharingMode sharing) { |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6964 } else { | 6980 } else { |
| 6965 new_map = Map::Copy(map); | 6981 new_map = Map::Copy(map); |
| 6966 } | 6982 } |
| 6967 | 6983 |
| 6968 Handle<TransitionArray> transitions = | 6984 Handle<TransitionArray> transitions = |
| 6969 Map::AddTransition(map, isolate->factory()->observed_symbol(), new_map, | 6985 Map::AddTransition(map, isolate->factory()->observed_symbol(), new_map, |
| 6970 FULL_TRANSITION); | 6986 FULL_TRANSITION); |
| 6971 | 6987 |
| 6972 map->set_transitions(*transitions); | 6988 map->set_transitions(*transitions); |
| 6973 | 6989 |
| 6974 new_map->set_is_observed(true); | 6990 new_map->set_is_observed(); |
| 6975 | 6991 |
| 6976 if (map->owns_descriptors()) { | 6992 if (map->owns_descriptors()) { |
| 6977 new_map->InitializeDescriptors(map->instance_descriptors()); | 6993 new_map->InitializeDescriptors(map->instance_descriptors()); |
| 6978 map->set_owns_descriptors(false); | 6994 map->set_owns_descriptors(false); |
| 6979 } | 6995 } |
| 6980 | 6996 |
| 6981 new_map->SetBackPointer(*map); | 6997 new_map->SetBackPointer(*map); |
| 6982 return new_map; | 6998 return new_map; |
| 6983 } | 6999 } |
| 6984 | 7000 |
| (...skipping 2332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9317 void String::PrintOn(FILE* file) { | 9333 void String::PrintOn(FILE* file) { |
| 9318 int length = this->length(); | 9334 int length = this->length(); |
| 9319 for (int i = 0; i < length; i++) { | 9335 for (int i = 0; i < length; i++) { |
| 9320 PrintF(file, "%c", Get(i)); | 9336 PrintF(file, "%c", Get(i)); |
| 9321 } | 9337 } |
| 9322 } | 9338 } |
| 9323 | 9339 |
| 9324 | 9340 |
| 9325 static void TrimEnumCache(Heap* heap, Map* map, DescriptorArray* descriptors) { | 9341 static void TrimEnumCache(Heap* heap, Map* map, DescriptorArray* descriptors) { |
| 9326 int live_enum = map->EnumLength(); | 9342 int live_enum = map->EnumLength(); |
| 9327 if (live_enum == Map::kInvalidEnumCache) { | 9343 if (live_enum == kInvalidEnumCacheSentinel) { |
| 9328 live_enum = map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM); | 9344 live_enum = map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM); |
| 9329 } | 9345 } |
| 9330 if (live_enum == 0) return descriptors->ClearEnumCache(); | 9346 if (live_enum == 0) return descriptors->ClearEnumCache(); |
| 9331 | 9347 |
| 9332 FixedArray* enum_cache = descriptors->GetEnumCache(); | 9348 FixedArray* enum_cache = descriptors->GetEnumCache(); |
| 9333 | 9349 |
| 9334 int to_trim = enum_cache->length() - live_enum; | 9350 int to_trim = enum_cache->length() - live_enum; |
| 9335 if (to_trim <= 0) return; | 9351 if (to_trim <= 0) return; |
| 9336 RightTrimFixedArray<FROM_GC>(heap, descriptors->GetEnumCache(), to_trim); | 9352 RightTrimFixedArray<FROM_GC>(heap, descriptors->GetEnumCache(), to_trim); |
| 9337 | 9353 |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9501 GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile)); | 9517 GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile)); |
| 9502 // No write barrier required, since the builtin is part of the root set. | 9518 // No write barrier required, since the builtin is part of the root set. |
| 9503 } | 9519 } |
| 9504 | 9520 |
| 9505 | 9521 |
| 9506 void JSFunction::MarkForConcurrentRecompilation() { | 9522 void JSFunction::MarkForConcurrentRecompilation() { |
| 9507 ASSERT(is_compiled() || GetIsolate()->DebuggerHasBreakPoints()); | 9523 ASSERT(is_compiled() || GetIsolate()->DebuggerHasBreakPoints()); |
| 9508 ASSERT(!IsOptimized()); | 9524 ASSERT(!IsOptimized()); |
| 9509 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); | 9525 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); |
| 9510 ASSERT(!shared()->is_generator()); | 9526 ASSERT(!shared()->is_generator()); |
| 9511 ASSERT(FLAG_concurrent_recompilation); | 9527 ASSERT(GetIsolate()->concurrent_recompilation_enabled()); |
| 9512 if (FLAG_trace_concurrent_recompilation) { | 9528 if (FLAG_trace_concurrent_recompilation) { |
| 9513 PrintF(" ** Marking "); | 9529 PrintF(" ** Marking "); |
| 9514 PrintName(); | 9530 PrintName(); |
| 9515 PrintF(" for concurrent recompilation.\n"); | 9531 PrintF(" for concurrent recompilation.\n"); |
| 9516 } | 9532 } |
| 9517 set_code_no_write_barrier( | 9533 set_code_no_write_barrier( |
| 9518 GetIsolate()->builtins()->builtin(Builtins::kConcurrentRecompile)); | 9534 GetIsolate()->builtins()->builtin(Builtins::kConcurrentRecompile)); |
| 9519 // No write barrier required, since the builtin is part of the root set. | 9535 // No write barrier required, since the builtin is part of the root set. |
| 9520 } | 9536 } |
| 9521 | 9537 |
| 9522 | 9538 |
| 9523 void JSFunction::MarkInRecompileQueue() { | 9539 void JSFunction::MarkInRecompileQueue() { |
| 9524 // We can only arrive here via the concurrent-recompilation builtin. If | 9540 // We can only arrive here via the concurrent-recompilation builtin. If |
| 9525 // break points were set, the code would point to the lazy-compile builtin. | 9541 // break points were set, the code would point to the lazy-compile builtin. |
| 9526 ASSERT(!GetIsolate()->DebuggerHasBreakPoints()); | 9542 ASSERT(!GetIsolate()->DebuggerHasBreakPoints()); |
| 9527 ASSERT(IsMarkedForConcurrentRecompilation() && !IsOptimized()); | 9543 ASSERT(IsMarkedForConcurrentRecompilation() && !IsOptimized()); |
| 9528 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); | 9544 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); |
| 9529 ASSERT(FLAG_concurrent_recompilation); | 9545 ASSERT(GetIsolate()->concurrent_recompilation_enabled()); |
| 9530 if (FLAG_trace_concurrent_recompilation) { | 9546 if (FLAG_trace_concurrent_recompilation) { |
| 9531 PrintF(" ** Queueing "); | 9547 PrintF(" ** Queueing "); |
| 9532 PrintName(); | 9548 PrintName(); |
| 9533 PrintF(" for concurrent recompilation.\n"); | 9549 PrintF(" for concurrent recompilation.\n"); |
| 9534 } | 9550 } |
| 9535 set_code_no_write_barrier( | 9551 set_code_no_write_barrier( |
| 9536 GetIsolate()->builtins()->builtin(Builtins::kInRecompileQueue)); | 9552 GetIsolate()->builtins()->builtin(Builtins::kInRecompileQueue)); |
| 9537 // No write barrier required, since the builtin is part of the root set. | 9553 // No write barrier required, since the builtin is part of the root set. |
| 9538 } | 9554 } |
| 9539 | 9555 |
| (...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10379 Address p = rinfo->target_reference(); | 10395 Address p = rinfo->target_reference(); |
| 10380 VisitExternalReference(&p); | 10396 VisitExternalReference(&p); |
| 10381 } | 10397 } |
| 10382 | 10398 |
| 10383 | 10399 |
| 10384 void Code::InvalidateRelocation() { | 10400 void Code::InvalidateRelocation() { |
| 10385 set_relocation_info(GetHeap()->empty_byte_array()); | 10401 set_relocation_info(GetHeap()->empty_byte_array()); |
| 10386 } | 10402 } |
| 10387 | 10403 |
| 10388 | 10404 |
| 10405 void Code::InvalidateEmbeddedObjects() { |
| 10406 Object* undefined = GetHeap()->undefined_value(); |
| 10407 int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
| 10408 for (RelocIterator it(this, mode_mask); !it.done(); it.next()) { |
| 10409 RelocInfo::Mode mode = it.rinfo()->rmode(); |
| 10410 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
| 10411 it.rinfo()->set_target_object(undefined, SKIP_WRITE_BARRIER); |
| 10412 } |
| 10413 } |
| 10414 } |
| 10415 |
| 10416 |
| 10389 void Code::Relocate(intptr_t delta) { | 10417 void Code::Relocate(intptr_t delta) { |
| 10390 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { | 10418 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { |
| 10391 it.rinfo()->apply(delta); | 10419 it.rinfo()->apply(delta); |
| 10392 } | 10420 } |
| 10393 CPU::FlushICache(instruction_start(), instruction_size()); | 10421 CPU::FlushICache(instruction_start(), instruction_size()); |
| 10394 } | 10422 } |
| 10395 | 10423 |
| 10396 | 10424 |
| 10397 void Code::CopyFrom(const CodeDesc& desc) { | 10425 void Code::CopyFrom(const CodeDesc& desc) { |
| 10398 ASSERT(Marking::Color(this) == Marking::WHITE_OBJECT); | 10426 ASSERT(Marking::Color(this) == Marking::WHITE_OBJECT); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10553 } | 10581 } |
| 10554 | 10582 |
| 10555 | 10583 |
| 10556 void Code::FindAllMaps(MapHandleList* maps) { | 10584 void Code::FindAllMaps(MapHandleList* maps) { |
| 10557 ASSERT(is_inline_cache_stub()); | 10585 ASSERT(is_inline_cache_stub()); |
| 10558 DisallowHeapAllocation no_allocation; | 10586 DisallowHeapAllocation no_allocation; |
| 10559 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 10587 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
| 10560 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10588 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
| 10561 RelocInfo* info = it.rinfo(); | 10589 RelocInfo* info = it.rinfo(); |
| 10562 Object* object = info->target_object(); | 10590 Object* object = info->target_object(); |
| 10563 if (object->IsMap()) maps->Add(Handle<Map>(Map::cast(object))); | 10591 if (object->IsMap()) maps->Add(handle(Map::cast(object))); |
| 10564 } | 10592 } |
| 10565 } | 10593 } |
| 10566 | 10594 |
| 10595 |
| 10596 void Code::FindAllTypes(TypeHandleList* types) { |
| 10597 ASSERT(is_inline_cache_stub()); |
| 10598 DisallowHeapAllocation no_allocation; |
| 10599 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
| 10600 Isolate* isolate = GetIsolate(); |
| 10601 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
| 10602 RelocInfo* info = it.rinfo(); |
| 10603 Object* object = info->target_object(); |
| 10604 if (object->IsMap()) { |
| 10605 Handle<Map> map(Map::cast(object)); |
| 10606 types->Add(handle(IC::MapToType(map), isolate)); |
| 10607 } |
| 10608 } |
| 10609 } |
| 10610 |
| 10567 | 10611 |
| 10568 void Code::ReplaceFirstMap(Map* replace_with) { | 10612 void Code::ReplaceFirstMap(Map* replace_with) { |
| 10569 ReplaceNthObject(1, GetHeap()->meta_map(), replace_with); | 10613 ReplaceNthObject(1, GetHeap()->meta_map(), replace_with); |
| 10570 } | 10614 } |
| 10571 | 10615 |
| 10572 | 10616 |
| 10573 Code* Code::FindFirstHandler() { | 10617 Code* Code::FindFirstHandler() { |
| 10574 ASSERT(is_inline_cache_stub()); | 10618 ASSERT(is_inline_cache_stub()); |
| 10575 DisallowHeapAllocation no_allocation; | 10619 DisallowHeapAllocation no_allocation; |
| 10576 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); | 10620 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11062 case DEBUG_STUB: return "DEBUG_STUB"; | 11106 case DEBUG_STUB: return "DEBUG_STUB"; |
| 11063 } | 11107 } |
| 11064 UNREACHABLE(); | 11108 UNREACHABLE(); |
| 11065 return NULL; | 11109 return NULL; |
| 11066 } | 11110 } |
| 11067 | 11111 |
| 11068 | 11112 |
| 11069 const char* Code::StubType2String(StubType type) { | 11113 const char* Code::StubType2String(StubType type) { |
| 11070 switch (type) { | 11114 switch (type) { |
| 11071 case NORMAL: return "NORMAL"; | 11115 case NORMAL: return "NORMAL"; |
| 11072 case FIELD: return "FIELD"; | 11116 case FAST: return "FAST"; |
| 11073 case CONSTANT: return "CONSTANT"; | |
| 11074 case CALLBACKS: return "CALLBACKS"; | |
| 11075 case INTERCEPTOR: return "INTERCEPTOR"; | |
| 11076 case TRANSITION: return "TRANSITION"; | |
| 11077 case NONEXISTENT: return "NONEXISTENT"; | |
| 11078 } | 11117 } |
| 11079 UNREACHABLE(); // keep the compiler happy | 11118 UNREACHABLE(); // keep the compiler happy |
| 11080 return NULL; | 11119 return NULL; |
| 11081 } | 11120 } |
| 11082 | 11121 |
| 11083 | 11122 |
| 11084 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) { | 11123 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) { |
| 11085 PrintF(out, "extra_ic_state = "); | 11124 PrintF(out, "extra_ic_state = "); |
| 11086 const char* name = NULL; | 11125 const char* name = NULL; |
| 11087 switch (kind) { | 11126 switch (kind) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 11102 if (name != NULL) { | 11141 if (name != NULL) { |
| 11103 PrintF(out, "%s\n", name); | 11142 PrintF(out, "%s\n", name); |
| 11104 } else { | 11143 } else { |
| 11105 PrintF(out, "%d\n", extra); | 11144 PrintF(out, "%d\n", extra); |
| 11106 } | 11145 } |
| 11107 } | 11146 } |
| 11108 | 11147 |
| 11109 | 11148 |
| 11110 void Code::Disassemble(const char* name, FILE* out) { | 11149 void Code::Disassemble(const char* name, FILE* out) { |
| 11111 PrintF(out, "kind = %s\n", Kind2String(kind())); | 11150 PrintF(out, "kind = %s\n", Kind2String(kind())); |
| 11151 if (has_major_key()) { |
| 11152 PrintF(out, "major_key = %s\n", |
| 11153 CodeStub::MajorName(CodeStub::GetMajorKey(this), true)); |
| 11154 } |
| 11112 if (is_inline_cache_stub()) { | 11155 if (is_inline_cache_stub()) { |
| 11113 PrintF(out, "ic_state = %s\n", ICState2String(ic_state())); | 11156 PrintF(out, "ic_state = %s\n", ICState2String(ic_state())); |
| 11114 PrintExtraICState(out, kind(), needs_extended_extra_ic_state(kind()) ? | 11157 PrintExtraICState(out, kind(), needs_extended_extra_ic_state(kind()) ? |
| 11115 extended_extra_ic_state() : extra_ic_state()); | 11158 extended_extra_ic_state() : extra_ic_state()); |
| 11116 if (ic_state() == MONOMORPHIC) { | 11159 if (ic_state() == MONOMORPHIC) { |
| 11117 PrintF(out, "type = %s\n", StubType2String(type())); | 11160 PrintF(out, "type = %s\n", StubType2String(type())); |
| 11118 } | 11161 } |
| 11119 if (is_call_stub() || is_keyed_call_stub()) { | 11162 if (is_call_stub() || is_keyed_call_stub()) { |
| 11120 PrintF(out, "argc = %d\n", arguments_count()); | 11163 PrintF(out, "argc = %d\n", arguments_count()); |
| 11121 } | 11164 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11203 | 11246 |
| 11204 PrintF(out, "RelocInfo (size = %d)\n", relocation_size()); | 11247 PrintF(out, "RelocInfo (size = %d)\n", relocation_size()); |
| 11205 for (RelocIterator it(this); !it.done(); it.next()) { | 11248 for (RelocIterator it(this); !it.done(); it.next()) { |
| 11206 it.rinfo()->Print(GetIsolate(), out); | 11249 it.rinfo()->Print(GetIsolate(), out); |
| 11207 } | 11250 } |
| 11208 PrintF(out, "\n"); | 11251 PrintF(out, "\n"); |
| 11209 } | 11252 } |
| 11210 #endif // ENABLE_DISASSEMBLER | 11253 #endif // ENABLE_DISASSEMBLER |
| 11211 | 11254 |
| 11212 | 11255 |
| 11256 Handle<FixedArray> JSObject::SetFastElementsCapacityAndLength( |
| 11257 Handle<JSObject> object, |
| 11258 int capacity, |
| 11259 int length, |
| 11260 SetFastElementsCapacitySmiMode smi_mode) { |
| 11261 CALL_HEAP_FUNCTION( |
| 11262 object->GetIsolate(), |
| 11263 object->SetFastElementsCapacityAndLength(capacity, length, smi_mode), |
| 11264 FixedArray); |
| 11265 } |
| 11266 |
| 11267 |
| 11213 MaybeObject* JSObject::SetFastElementsCapacityAndLength( | 11268 MaybeObject* JSObject::SetFastElementsCapacityAndLength( |
| 11214 int capacity, | 11269 int capacity, |
| 11215 int length, | 11270 int length, |
| 11216 SetFastElementsCapacitySmiMode smi_mode) { | 11271 SetFastElementsCapacitySmiMode smi_mode) { |
| 11217 Heap* heap = GetHeap(); | 11272 Heap* heap = GetHeap(); |
| 11218 // We should never end in here with a pixel or external array. | 11273 // We should never end in here with a pixel or external array. |
| 11219 ASSERT(!HasExternalArrayElements()); | 11274 ASSERT(!HasExternalArrayElements()); |
| 11220 ASSERT(!map()->is_observed()); | |
| 11221 | 11275 |
| 11222 // Allocate a new fast elements backing store. | 11276 // Allocate a new fast elements backing store. |
| 11223 FixedArray* new_elements; | 11277 FixedArray* new_elements; |
| 11224 MaybeObject* maybe = heap->AllocateUninitializedFixedArray(capacity); | 11278 MaybeObject* maybe = heap->AllocateUninitializedFixedArray(capacity); |
| 11225 if (!maybe->To(&new_elements)) return maybe; | 11279 if (!maybe->To(&new_elements)) return maybe; |
| 11226 | 11280 |
| 11227 ElementsKind elements_kind = GetElementsKind(); | 11281 ElementsKind elements_kind = GetElementsKind(); |
| 11228 ElementsKind new_elements_kind; | 11282 ElementsKind new_elements_kind; |
| 11229 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it, | 11283 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it, |
| 11230 // or if it's allowed and the old elements array contained only SMIs. | 11284 // or if it's allowed and the old elements array contained only SMIs. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11289 FLAG_weak_embedded_maps_in_optimized_code; | 11343 FLAG_weak_embedded_maps_in_optimized_code; |
| 11290 } | 11344 } |
| 11291 | 11345 |
| 11292 if (object->IsJSObject()) { | 11346 if (object->IsJSObject()) { |
| 11293 return FLAG_weak_embedded_objects_in_optimized_code; | 11347 return FLAG_weak_embedded_objects_in_optimized_code; |
| 11294 } | 11348 } |
| 11295 | 11349 |
| 11296 return false; | 11350 return false; |
| 11297 } | 11351 } |
| 11298 | 11352 |
| 11353 |
| 11354 void JSObject::SetFastDoubleElementsCapacityAndLength(Handle<JSObject> object, |
| 11355 int capacity, |
| 11356 int length) { |
| 11357 CALL_HEAP_FUNCTION_VOID( |
| 11358 object->GetIsolate(), |
| 11359 object->SetFastDoubleElementsCapacityAndLength(capacity, length)); |
| 11360 } |
| 11361 |
| 11362 |
| 11299 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( | 11363 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( |
| 11300 int capacity, | 11364 int capacity, |
| 11301 int length) { | 11365 int length) { |
| 11302 Heap* heap = GetHeap(); | 11366 Heap* heap = GetHeap(); |
| 11303 // We should never end in here with a pixel or external array. | 11367 // We should never end in here with a pixel or external array. |
| 11304 ASSERT(!HasExternalArrayElements()); | 11368 ASSERT(!HasExternalArrayElements()); |
| 11305 ASSERT(!map()->is_observed()); | |
| 11306 | 11369 |
| 11307 FixedArrayBase* elems; | 11370 FixedArrayBase* elems; |
| 11308 { MaybeObject* maybe_obj = | 11371 { MaybeObject* maybe_obj = |
| 11309 heap->AllocateUninitializedFixedDoubleArray(capacity); | 11372 heap->AllocateUninitializedFixedDoubleArray(capacity); |
| 11310 if (!maybe_obj->To(&elems)) return maybe_obj; | 11373 if (!maybe_obj->To(&elems)) return maybe_obj; |
| 11311 } | 11374 } |
| 11312 | 11375 |
| 11313 ElementsKind elements_kind = GetElementsKind(); | 11376 ElementsKind elements_kind = GetElementsKind(); |
| 11314 ElementsKind new_elements_kind = elements_kind; | 11377 ElementsKind new_elements_kind = elements_kind; |
| 11315 if (IsHoleyElementsKind(elements_kind)) { | 11378 if (IsHoleyElementsKind(elements_kind)) { |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11444 List<uint32_t> indices; | 11507 List<uint32_t> indices; |
| 11445 List<Handle<Object> > old_values; | 11508 List<Handle<Object> > old_values; |
| 11446 Handle<Object> old_length_handle(self->length(), isolate); | 11509 Handle<Object> old_length_handle(self->length(), isolate); |
| 11447 Handle<Object> new_length_handle(len, isolate); | 11510 Handle<Object> new_length_handle(len, isolate); |
| 11448 uint32_t old_length = 0; | 11511 uint32_t old_length = 0; |
| 11449 CHECK(old_length_handle->ToArrayIndex(&old_length)); | 11512 CHECK(old_length_handle->ToArrayIndex(&old_length)); |
| 11450 uint32_t new_length = 0; | 11513 uint32_t new_length = 0; |
| 11451 if (!new_length_handle->ToArrayIndex(&new_length)) | 11514 if (!new_length_handle->ToArrayIndex(&new_length)) |
| 11452 return Failure::InternalError(); | 11515 return Failure::InternalError(); |
| 11453 | 11516 |
| 11454 // Observed arrays should always be in dictionary mode; | |
| 11455 // if they were in fast mode, the below is slower than necessary | |
| 11456 // as it iterates over the array backing store multiple times. | |
| 11457 ASSERT(self->HasDictionaryElements()); | |
| 11458 static const PropertyAttributes kNoAttrFilter = NONE; | 11517 static const PropertyAttributes kNoAttrFilter = NONE; |
| 11459 int num_elements = self->NumberOfLocalElements(kNoAttrFilter); | 11518 int num_elements = self->NumberOfLocalElements(kNoAttrFilter); |
| 11460 if (num_elements > 0) { | 11519 if (num_elements > 0) { |
| 11461 if (old_length == static_cast<uint32_t>(num_elements)) { | 11520 if (old_length == static_cast<uint32_t>(num_elements)) { |
| 11462 // Simple case for arrays without holes. | 11521 // Simple case for arrays without holes. |
| 11463 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { | 11522 for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { |
| 11464 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break; | 11523 if (!GetOldValue(isolate, self, i, &old_values, &indices)) break; |
| 11465 } | 11524 } |
| 11466 } else { | 11525 } else { |
| 11467 // For sparse arrays, only iterate over existing elements. | 11526 // For sparse arrays, only iterate over existing elements. |
| 11527 // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over |
| 11528 // the to-be-removed indices twice. |
| 11468 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); | 11529 Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); |
| 11469 self->GetLocalElementKeys(*keys, kNoAttrFilter); | 11530 self->GetLocalElementKeys(*keys, kNoAttrFilter); |
| 11470 while (num_elements-- > 0) { | 11531 while (num_elements-- > 0) { |
| 11471 uint32_t index = NumberToUint32(keys->get(num_elements)); | 11532 uint32_t index = NumberToUint32(keys->get(num_elements)); |
| 11472 if (index < new_length) break; | 11533 if (index < new_length) break; |
| 11473 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break; | 11534 if (!GetOldValue(isolate, self, index, &old_values, &indices)) break; |
| 11474 } | 11535 } |
| 11475 } | 11536 } |
| 11476 } | 11537 } |
| 11477 | 11538 |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11626 start_indexes_[g] = start_indexes_[g - 1] + count; | 11687 start_indexes_[g] = start_indexes_[g - 1] + count; |
| 11627 } | 11688 } |
| 11628 } | 11689 } |
| 11629 | 11690 |
| 11630 | 11691 |
| 11631 DependentCode* DependentCode::ForObject(Handle<HeapObject> object, | 11692 DependentCode* DependentCode::ForObject(Handle<HeapObject> object, |
| 11632 DependencyGroup group) { | 11693 DependencyGroup group) { |
| 11633 AllowDeferredHandleDereference dependencies_are_safe; | 11694 AllowDeferredHandleDereference dependencies_are_safe; |
| 11634 if (group == DependentCode::kPropertyCellChangedGroup) { | 11695 if (group == DependentCode::kPropertyCellChangedGroup) { |
| 11635 return Handle<PropertyCell>::cast(object)->dependent_code(); | 11696 return Handle<PropertyCell>::cast(object)->dependent_code(); |
| 11697 } else if (group == DependentCode::kAllocationSiteTenuringChangedGroup || |
| 11698 group == DependentCode::kAllocationSiteTransitionChangedGroup) { |
| 11699 return Handle<AllocationSite>::cast(object)->dependent_code(); |
| 11636 } | 11700 } |
| 11637 return Handle<Map>::cast(object)->dependent_code(); | 11701 return Handle<Map>::cast(object)->dependent_code(); |
| 11638 } | 11702 } |
| 11639 | 11703 |
| 11640 | 11704 |
| 11641 Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries, | 11705 Handle<DependentCode> DependentCode::Insert(Handle<DependentCode> entries, |
| 11642 DependencyGroup group, | 11706 DependencyGroup group, |
| 11643 Handle<Object> object) { | 11707 Handle<Object> object) { |
| 11644 GroupStartIndexes starts(*entries); | 11708 GroupStartIndexes starts(*entries); |
| 11645 int start = starts.at(group); | 11709 int start = starts.at(group); |
| 11646 int end = starts.at(group + 1); | 11710 int end = starts.at(group + 1); |
| 11647 int number_of_entries = starts.number_of_entries(); | 11711 int number_of_entries = starts.number_of_entries(); |
| 11648 if (start < end && entries->object_at(end - 1) == *object) { | 11712 // Check for existing entry to avoid duplicates. |
| 11649 // Do not append the compilation info if it is already in the array. | 11713 for (int i = start; i < end; i++) { |
| 11650 // It is sufficient to just check only the last element because | 11714 if (entries->object_at(i) == *object) return entries; |
| 11651 // we process embedded maps of an optimized code in one batch. | |
| 11652 return entries; | |
| 11653 } | 11715 } |
| 11654 if (entries->length() < kCodesStartIndex + number_of_entries + 1) { | 11716 if (entries->length() < kCodesStartIndex + number_of_entries + 1) { |
| 11655 Factory* factory = entries->GetIsolate()->factory(); | 11717 Factory* factory = entries->GetIsolate()->factory(); |
| 11656 int capacity = kCodesStartIndex + number_of_entries + 1; | 11718 int capacity = kCodesStartIndex + number_of_entries + 1; |
| 11657 if (capacity > 5) capacity = capacity * 5 / 4; | 11719 if (capacity > 5) capacity = capacity * 5 / 4; |
| 11658 Handle<DependentCode> new_entries = Handle<DependentCode>::cast( | 11720 Handle<DependentCode> new_entries = Handle<DependentCode>::cast( |
| 11659 factory->CopySizeFixedArray(entries, capacity, TENURED)); | 11721 factory->CopySizeFixedArray(entries, capacity, TENURED)); |
| 11660 // The number of codes can change after GC. | 11722 // The number of codes can change after GC. |
| 11661 starts.Recompute(*entries); | 11723 starts.Recompute(*entries); |
| 11662 start = starts.at(group); | 11724 start = starts.at(group); |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11925 return JSObject::cast(proto)->GetLocalElementAccessorPair(index); | 11987 return JSObject::cast(proto)->GetLocalElementAccessorPair(index); |
| 11926 } | 11988 } |
| 11927 | 11989 |
| 11928 // Check for lookup interceptor. | 11990 // Check for lookup interceptor. |
| 11929 if (HasIndexedInterceptor()) return NULL; | 11991 if (HasIndexedInterceptor()) return NULL; |
| 11930 | 11992 |
| 11931 return GetElementsAccessor()->GetAccessorPair(this, this, index); | 11993 return GetElementsAccessor()->GetAccessorPair(this, this, index); |
| 11932 } | 11994 } |
| 11933 | 11995 |
| 11934 | 11996 |
| 11935 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, | 11997 Handle<Object> JSObject::SetElementWithInterceptor( |
| 11936 Object* value, | 11998 Handle<JSObject> object, |
| 11937 PropertyAttributes attributes, | 11999 uint32_t index, |
| 11938 StrictModeFlag strict_mode, | 12000 Handle<Object> value, |
| 11939 bool check_prototype, | 12001 PropertyAttributes attributes, |
| 11940 SetPropertyMode set_mode) { | 12002 StrictModeFlag strict_mode, |
| 11941 Isolate* isolate = GetIsolate(); | 12003 bool check_prototype, |
| 11942 HandleScope scope(isolate); | 12004 SetPropertyMode set_mode) { |
| 12005 Isolate* isolate = object->GetIsolate(); |
| 11943 | 12006 |
| 11944 // Make sure that the top context does not change when doing | 12007 // Make sure that the top context does not change when doing |
| 11945 // callbacks or interceptor calls. | 12008 // callbacks or interceptor calls. |
| 11946 AssertNoContextChange ncc(isolate); | 12009 AssertNoContextChange ncc(isolate); |
| 11947 | 12010 |
| 11948 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 12011 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); |
| 11949 Handle<JSObject> this_handle(this); | |
| 11950 Handle<Object> value_handle(value, isolate); | |
| 11951 if (!interceptor->setter()->IsUndefined()) { | 12012 if (!interceptor->setter()->IsUndefined()) { |
| 11952 v8::IndexedPropertySetterCallback setter = | 12013 v8::IndexedPropertySetterCallback setter = |
| 11953 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); | 12014 v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter()); |
| 11954 LOG(isolate, | 12015 LOG(isolate, |
| 11955 ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); | 12016 ApiIndexedPropertyAccess("interceptor-indexed-set", *object, index)); |
| 11956 PropertyCallbackArguments args(isolate, interceptor->data(), this, this); | 12017 PropertyCallbackArguments args(isolate, interceptor->data(), *object, |
| 12018 *object); |
| 11957 v8::Handle<v8::Value> result = | 12019 v8::Handle<v8::Value> result = |
| 11958 args.Call(setter, index, v8::Utils::ToLocal(value_handle)); | 12020 args.Call(setter, index, v8::Utils::ToLocal(value)); |
| 11959 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 12021 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 11960 if (!result.IsEmpty()) return *value_handle; | 12022 if (!result.IsEmpty()) return value; |
| 11961 } | 12023 } |
| 11962 MaybeObject* raw_result = | 12024 |
| 11963 this_handle->SetElementWithoutInterceptor(index, | 12025 return SetElementWithoutInterceptor(object, index, value, attributes, |
| 11964 *value_handle, | 12026 strict_mode, |
| 11965 attributes, | 12027 check_prototype, |
| 11966 strict_mode, | 12028 set_mode); |
| 11967 check_prototype, | |
| 11968 set_mode); | |
| 11969 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | |
| 11970 return raw_result; | |
| 11971 } | 12029 } |
| 11972 | 12030 |
| 11973 | 12031 |
| 11974 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, | 12032 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, |
| 11975 Object* structure, | 12033 Object* structure, |
| 11976 uint32_t index, | 12034 uint32_t index, |
| 11977 Object* holder) { | 12035 Object* holder) { |
| 11978 Isolate* isolate = GetIsolate(); | 12036 Isolate* isolate = GetIsolate(); |
| 11979 ASSERT(!structure->IsForeign()); | 12037 ASSERT(!structure->IsForeign()); |
| 11980 | 12038 |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12108 return false; | 12166 return false; |
| 12109 } | 12167 } |
| 12110 FixedArray* arguments = FixedArray::cast(elements->get(1)); | 12168 FixedArray* arguments = FixedArray::cast(elements->get(1)); |
| 12111 return arguments->IsDictionary(); | 12169 return arguments->IsDictionary(); |
| 12112 } | 12170 } |
| 12113 | 12171 |
| 12114 | 12172 |
| 12115 // Adding n elements in fast case is O(n*n). | 12173 // Adding n elements in fast case is O(n*n). |
| 12116 // Note: revisit design to have dual undefined values to capture absent | 12174 // Note: revisit design to have dual undefined values to capture absent |
| 12117 // elements. | 12175 // elements. |
| 12118 MaybeObject* JSObject::SetFastElement(uint32_t index, | 12176 Handle<Object> JSObject::SetFastElement(Handle<JSObject> object, |
| 12119 Object* value, | 12177 uint32_t index, |
| 12120 StrictModeFlag strict_mode, | 12178 Handle<Object> value, |
| 12121 bool check_prototype) { | 12179 StrictModeFlag strict_mode, |
| 12122 ASSERT(HasFastSmiOrObjectElements() || | 12180 bool check_prototype) { |
| 12123 HasFastArgumentsElements()); | 12181 ASSERT(object->HasFastSmiOrObjectElements() || |
| 12182 object->HasFastArgumentsElements()); |
| 12183 |
| 12184 Isolate* isolate = object->GetIsolate(); |
| 12124 | 12185 |
| 12125 // Array optimizations rely on the prototype lookups of Array objects always | 12186 // Array optimizations rely on the prototype lookups of Array objects always |
| 12126 // returning undefined. If there is a store to the initial prototype object, | 12187 // returning undefined. If there is a store to the initial prototype object, |
| 12127 // make sure all of these optimizations are invalidated. | 12188 // make sure all of these optimizations are invalidated. |
| 12128 Isolate* isolate(GetIsolate()); | 12189 if (isolate->is_initial_object_prototype(*object) || |
| 12129 if (isolate->is_initial_object_prototype(this) || | 12190 isolate->is_initial_array_prototype(*object)) { |
| 12130 isolate->is_initial_array_prototype(this)) { | 12191 object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate, |
| 12131 HandleScope scope(GetIsolate()); | |
| 12132 map()->dependent_code()->DeoptimizeDependentCodeGroup( | |
| 12133 GetIsolate(), | |
| 12134 DependentCode::kElementsCantBeAddedGroup); | 12192 DependentCode::kElementsCantBeAddedGroup); |
| 12135 } | 12193 } |
| 12136 | 12194 |
| 12137 FixedArray* backing_store = FixedArray::cast(elements()); | 12195 Handle<FixedArray> backing_store(FixedArray::cast(object->elements())); |
| 12138 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) { | 12196 if (backing_store->map() == |
| 12139 backing_store = FixedArray::cast(backing_store->get(1)); | 12197 isolate->heap()->non_strict_arguments_elements_map()) { |
| 12198 backing_store = handle(FixedArray::cast(backing_store->get(1))); |
| 12140 } else { | 12199 } else { |
| 12141 MaybeObject* maybe = EnsureWritableFastElements(); | 12200 backing_store = EnsureWritableFastElements(object); |
| 12142 if (!maybe->To(&backing_store)) return maybe; | |
| 12143 } | 12201 } |
| 12144 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); | 12202 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); |
| 12145 | 12203 |
| 12146 if (check_prototype && | 12204 if (check_prototype && |
| 12147 (index >= capacity || backing_store->get(index)->IsTheHole())) { | 12205 (index >= capacity || backing_store->get(index)->IsTheHole())) { |
| 12148 bool found; | 12206 bool found; |
| 12149 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, | 12207 Handle<Object> result = SetElementWithCallbackSetterInPrototypes( |
| 12150 value, | 12208 object, index, value, &found, strict_mode); |
| 12151 &found, | |
| 12152 strict_mode); | |
| 12153 if (found) return result; | 12209 if (found) return result; |
| 12154 } | 12210 } |
| 12155 | 12211 |
| 12156 uint32_t new_capacity = capacity; | 12212 uint32_t new_capacity = capacity; |
| 12157 // Check if the length property of this object needs to be updated. | 12213 // Check if the length property of this object needs to be updated. |
| 12158 uint32_t array_length = 0; | 12214 uint32_t array_length = 0; |
| 12159 bool must_update_array_length = false; | 12215 bool must_update_array_length = false; |
| 12160 bool introduces_holes = true; | 12216 bool introduces_holes = true; |
| 12161 if (IsJSArray()) { | 12217 if (object->IsJSArray()) { |
| 12162 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); | 12218 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length)); |
| 12163 introduces_holes = index > array_length; | 12219 introduces_holes = index > array_length; |
| 12164 if (index >= array_length) { | 12220 if (index >= array_length) { |
| 12165 must_update_array_length = true; | 12221 must_update_array_length = true; |
| 12166 array_length = index + 1; | 12222 array_length = index + 1; |
| 12167 } | 12223 } |
| 12168 } else { | 12224 } else { |
| 12169 introduces_holes = index >= capacity; | 12225 introduces_holes = index >= capacity; |
| 12170 } | 12226 } |
| 12171 | 12227 |
| 12172 // If the array is growing, and it's not growth by a single element at the | 12228 // If the array is growing, and it's not growth by a single element at the |
| 12173 // end, make sure that the ElementsKind is HOLEY. | 12229 // end, make sure that the ElementsKind is HOLEY. |
| 12174 ElementsKind elements_kind = GetElementsKind(); | 12230 ElementsKind elements_kind = object->GetElementsKind(); |
| 12175 if (introduces_holes && | 12231 if (introduces_holes && |
| 12176 IsFastElementsKind(elements_kind) && | 12232 IsFastElementsKind(elements_kind) && |
| 12177 !IsFastHoleyElementsKind(elements_kind)) { | 12233 !IsFastHoleyElementsKind(elements_kind)) { |
| 12178 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); | 12234 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); |
| 12179 MaybeObject* maybe = TransitionElementsKind(transitioned_kind); | 12235 TransitionElementsKind(object, transitioned_kind); |
| 12180 if (maybe->IsFailure()) return maybe; | |
| 12181 } | 12236 } |
| 12182 | 12237 |
| 12183 // Check if the capacity of the backing store needs to be increased, or if | 12238 // Check if the capacity of the backing store needs to be increased, or if |
| 12184 // a transition to slow elements is necessary. | 12239 // a transition to slow elements is necessary. |
| 12185 if (index >= capacity) { | 12240 if (index >= capacity) { |
| 12186 bool convert_to_slow = true; | 12241 bool convert_to_slow = true; |
| 12187 if ((index - capacity) < kMaxGap) { | 12242 if ((index - capacity) < kMaxGap) { |
| 12188 new_capacity = NewElementsCapacity(index + 1); | 12243 new_capacity = NewElementsCapacity(index + 1); |
| 12189 ASSERT(new_capacity > index); | 12244 ASSERT(new_capacity > index); |
| 12190 if (!ShouldConvertToSlowElements(new_capacity)) { | 12245 if (!object->ShouldConvertToSlowElements(new_capacity)) { |
| 12191 convert_to_slow = false; | 12246 convert_to_slow = false; |
| 12192 } | 12247 } |
| 12193 } | 12248 } |
| 12194 if (convert_to_slow) { | 12249 if (convert_to_slow) { |
| 12195 MaybeObject* result = NormalizeElements(); | 12250 NormalizeElements(object); |
| 12196 if (result->IsFailure()) return result; | 12251 return SetDictionaryElement(object, index, value, NONE, strict_mode, |
| 12197 return SetDictionaryElement(index, value, NONE, strict_mode, | |
| 12198 check_prototype); | 12252 check_prototype); |
| 12199 } | 12253 } |
| 12200 } | 12254 } |
| 12201 // Convert to fast double elements if appropriate. | 12255 // Convert to fast double elements if appropriate. |
| 12202 if (HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { | 12256 if (object->HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { |
| 12203 // Consider fixing the boilerplate as well if we have one. | 12257 // Consider fixing the boilerplate as well if we have one. |
| 12204 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) | 12258 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) |
| 12205 ? FAST_HOLEY_DOUBLE_ELEMENTS | 12259 ? FAST_HOLEY_DOUBLE_ELEMENTS |
| 12206 : FAST_DOUBLE_ELEMENTS; | 12260 : FAST_DOUBLE_ELEMENTS; |
| 12207 | 12261 |
| 12208 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); | 12262 UpdateAllocationSite(object, to_kind); |
| 12209 if (maybe_failure->IsFailure()) return maybe_failure; | |
| 12210 | 12263 |
| 12211 MaybeObject* maybe = | 12264 SetFastDoubleElementsCapacityAndLength(object, new_capacity, array_length); |
| 12212 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); | 12265 FixedDoubleArray::cast(object->elements())->set(index, value->Number()); |
| 12213 if (maybe->IsFailure()) return maybe; | 12266 object->ValidateElements(); |
| 12214 FixedDoubleArray::cast(elements())->set(index, value->Number()); | |
| 12215 ValidateElements(); | |
| 12216 return value; | 12267 return value; |
| 12217 } | 12268 } |
| 12218 // Change elements kind from Smi-only to generic FAST if necessary. | 12269 // Change elements kind from Smi-only to generic FAST if necessary. |
| 12219 if (HasFastSmiElements() && !value->IsSmi()) { | 12270 if (object->HasFastSmiElements() && !value->IsSmi()) { |
| 12220 Map* new_map; | 12271 ElementsKind kind = object->HasFastHoleyElements() |
| 12221 ElementsKind kind = HasFastHoleyElements() | |
| 12222 ? FAST_HOLEY_ELEMENTS | 12272 ? FAST_HOLEY_ELEMENTS |
| 12223 : FAST_ELEMENTS; | 12273 : FAST_ELEMENTS; |
| 12224 | 12274 |
| 12225 MaybeObject* maybe_failure = UpdateAllocationSite(kind); | 12275 UpdateAllocationSite(object, kind); |
| 12226 if (maybe_failure->IsFailure()) return maybe_failure; | 12276 Handle<Map> new_map = GetElementsTransitionMap(object, kind); |
| 12227 | 12277 object->set_map(*new_map); |
| 12228 MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(), | 12278 ASSERT(IsFastObjectElementsKind(object->GetElementsKind())); |
| 12229 kind); | |
| 12230 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | |
| 12231 | |
| 12232 set_map(new_map); | |
| 12233 } | 12279 } |
| 12234 // Increase backing store capacity if that's been decided previously. | 12280 // Increase backing store capacity if that's been decided previously. |
| 12235 if (new_capacity != capacity) { | 12281 if (new_capacity != capacity) { |
| 12236 FixedArray* new_elements; | |
| 12237 SetFastElementsCapacitySmiMode smi_mode = | 12282 SetFastElementsCapacitySmiMode smi_mode = |
| 12238 value->IsSmi() && HasFastSmiElements() | 12283 value->IsSmi() && object->HasFastSmiElements() |
| 12239 ? kAllowSmiElements | 12284 ? kAllowSmiElements |
| 12240 : kDontAllowSmiElements; | 12285 : kDontAllowSmiElements; |
| 12241 { MaybeObject* maybe = | 12286 Handle<FixedArray> new_elements = |
| 12242 SetFastElementsCapacityAndLength(new_capacity, | 12287 SetFastElementsCapacityAndLength(object, new_capacity, array_length, |
| 12243 array_length, | 12288 smi_mode); |
| 12244 smi_mode); | 12289 new_elements->set(index, *value); |
| 12245 if (!maybe->To(&new_elements)) return maybe; | 12290 object->ValidateElements(); |
| 12246 } | |
| 12247 new_elements->set(index, value); | |
| 12248 ValidateElements(); | |
| 12249 return value; | 12291 return value; |
| 12250 } | 12292 } |
| 12251 | 12293 |
| 12252 // Finally, set the new element and length. | 12294 // Finally, set the new element and length. |
| 12253 ASSERT(elements()->IsFixedArray()); | 12295 ASSERT(object->elements()->IsFixedArray()); |
| 12254 backing_store->set(index, value); | 12296 backing_store->set(index, *value); |
| 12255 if (must_update_array_length) { | 12297 if (must_update_array_length) { |
| 12256 JSArray::cast(this)->set_length(Smi::FromInt(array_length)); | 12298 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); |
| 12257 } | 12299 } |
| 12258 return value; | 12300 return value; |
| 12259 } | 12301 } |
| 12260 | 12302 |
| 12261 | 12303 |
| 12262 MaybeObject* JSObject::SetDictionaryElement(uint32_t index, | 12304 Handle<Object> JSObject::SetDictionaryElement(Handle<JSObject> object, |
| 12263 Object* value_raw, | 12305 uint32_t index, |
| 12264 PropertyAttributes attributes, | 12306 Handle<Object> value, |
| 12265 StrictModeFlag strict_mode, | 12307 PropertyAttributes attributes, |
| 12266 bool check_prototype, | 12308 StrictModeFlag strict_mode, |
| 12267 SetPropertyMode set_mode) { | 12309 bool check_prototype, |
| 12268 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 12310 SetPropertyMode set_mode) { |
| 12269 Isolate* isolate = GetIsolate(); | 12311 ASSERT(object->HasDictionaryElements() || |
| 12270 Heap* heap = isolate->heap(); | 12312 object->HasDictionaryArgumentsElements()); |
| 12271 Handle<JSObject> self(this); | 12313 Isolate* isolate = object->GetIsolate(); |
| 12272 Handle<Object> value(value_raw, isolate); | |
| 12273 | 12314 |
| 12274 // Insert element in the dictionary. | 12315 // Insert element in the dictionary. |
| 12275 Handle<FixedArray> elements(FixedArray::cast(this->elements())); | 12316 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
| 12276 bool is_arguments = | 12317 bool is_arguments = |
| 12277 (elements->map() == heap->non_strict_arguments_elements_map()); | 12318 (elements->map() == isolate->heap()->non_strict_arguments_elements_map()); |
| 12278 Handle<SeededNumberDictionary> dictionary(is_arguments | 12319 Handle<SeededNumberDictionary> dictionary(is_arguments |
| 12279 ? SeededNumberDictionary::cast(elements->get(1)) | 12320 ? SeededNumberDictionary::cast(elements->get(1)) |
| 12280 : SeededNumberDictionary::cast(*elements)); | 12321 : SeededNumberDictionary::cast(*elements)); |
| 12281 | 12322 |
| 12282 int entry = dictionary->FindEntry(index); | 12323 int entry = dictionary->FindEntry(index); |
| 12283 if (entry != SeededNumberDictionary::kNotFound) { | 12324 if (entry != SeededNumberDictionary::kNotFound) { |
| 12284 Handle<Object> element(dictionary->ValueAt(entry), isolate); | 12325 Handle<Object> element(dictionary->ValueAt(entry), isolate); |
| 12285 PropertyDetails details = dictionary->DetailsAt(entry); | 12326 PropertyDetails details = dictionary->DetailsAt(entry); |
| 12286 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { | 12327 if (details.type() == CALLBACKS && set_mode == SET_PROPERTY) { |
| 12287 Handle<Object> result = SetElementWithCallback(self, element, index, | 12328 return SetElementWithCallback(object, element, index, value, object, |
| 12288 value, self, strict_mode); | 12329 strict_mode); |
| 12289 RETURN_IF_EMPTY_HANDLE(isolate, result); | |
| 12290 return *result; | |
| 12291 } else { | 12330 } else { |
| 12292 dictionary->UpdateMaxNumberKey(index); | 12331 dictionary->UpdateMaxNumberKey(index); |
| 12293 // If a value has not been initialized we allow writing to it even if it | 12332 // If a value has not been initialized we allow writing to it even if it |
| 12294 // is read-only (a declared const that has not been initialized). If a | 12333 // is read-only (a declared const that has not been initialized). If a |
| 12295 // value is being defined we skip attribute checks completely. | 12334 // value is being defined we skip attribute checks completely. |
| 12296 if (set_mode == DEFINE_PROPERTY) { | 12335 if (set_mode == DEFINE_PROPERTY) { |
| 12297 details = PropertyDetails( | 12336 details = PropertyDetails( |
| 12298 attributes, NORMAL, details.dictionary_index()); | 12337 attributes, NORMAL, details.dictionary_index()); |
| 12299 dictionary->DetailsAtPut(entry, details); | 12338 dictionary->DetailsAtPut(entry, details); |
| 12300 } else if (details.IsReadOnly() && !element->IsTheHole()) { | 12339 } else if (details.IsReadOnly() && !element->IsTheHole()) { |
| 12301 if (strict_mode == kNonStrictMode) { | 12340 if (strict_mode == kNonStrictMode) { |
| 12302 return isolate->heap()->undefined_value(); | 12341 return isolate->factory()->undefined_value(); |
| 12303 } else { | 12342 } else { |
| 12304 Handle<Object> holder(this, isolate); | |
| 12305 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12343 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 12306 Handle<Object> args[2] = { number, holder }; | 12344 Handle<Object> args[2] = { number, object }; |
| 12307 Handle<Object> error = | 12345 Handle<Object> error = |
| 12308 isolate->factory()->NewTypeError("strict_read_only_property", | 12346 isolate->factory()->NewTypeError("strict_read_only_property", |
| 12309 HandleVector(args, 2)); | 12347 HandleVector(args, 2)); |
| 12310 return isolate->Throw(*error); | 12348 isolate->Throw(*error); |
| 12349 return Handle<Object>(); |
| 12311 } | 12350 } |
| 12312 } | 12351 } |
| 12313 // Elements of the arguments object in slow mode might be slow aliases. | 12352 // Elements of the arguments object in slow mode might be slow aliases. |
| 12314 if (is_arguments && element->IsAliasedArgumentsEntry()) { | 12353 if (is_arguments && element->IsAliasedArgumentsEntry()) { |
| 12315 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*element); | 12354 Handle<AliasedArgumentsEntry> entry = |
| 12316 Context* context = Context::cast(elements->get(0)); | 12355 Handle<AliasedArgumentsEntry>::cast(element); |
| 12356 Handle<Context> context(Context::cast(elements->get(0))); |
| 12317 int context_index = entry->aliased_context_slot(); | 12357 int context_index = entry->aliased_context_slot(); |
| 12318 ASSERT(!context->get(context_index)->IsTheHole()); | 12358 ASSERT(!context->get(context_index)->IsTheHole()); |
| 12319 context->set(context_index, *value); | 12359 context->set(context_index, *value); |
| 12320 // For elements that are still writable we keep slow aliasing. | 12360 // For elements that are still writable we keep slow aliasing. |
| 12321 if (!details.IsReadOnly()) value = element; | 12361 if (!details.IsReadOnly()) value = element; |
| 12322 } | 12362 } |
| 12323 dictionary->ValueAtPut(entry, *value); | 12363 dictionary->ValueAtPut(entry, *value); |
| 12324 } | 12364 } |
| 12325 } else { | 12365 } else { |
| 12326 // Index not already used. Look for an accessor in the prototype chain. | 12366 // Index not already used. Look for an accessor in the prototype chain. |
| 12327 // Can cause GC! | 12367 // Can cause GC! |
| 12328 if (check_prototype) { | 12368 if (check_prototype) { |
| 12329 bool found; | 12369 bool found; |
| 12330 MaybeObject* result = SetElementWithCallbackSetterInPrototypes( | 12370 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object, |
| 12331 index, *value, &found, strict_mode); | 12371 index, value, &found, strict_mode); |
| 12332 if (found) return result; | 12372 if (found) return result; |
| 12333 } | 12373 } |
| 12374 |
| 12334 // When we set the is_extensible flag to false we always force the | 12375 // When we set the is_extensible flag to false we always force the |
| 12335 // element into dictionary mode (and force them to stay there). | 12376 // element into dictionary mode (and force them to stay there). |
| 12336 if (!self->map()->is_extensible()) { | 12377 if (!object->map()->is_extensible()) { |
| 12337 if (strict_mode == kNonStrictMode) { | 12378 if (strict_mode == kNonStrictMode) { |
| 12338 return isolate->heap()->undefined_value(); | 12379 return isolate->factory()->undefined_value(); |
| 12339 } else { | 12380 } else { |
| 12340 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12381 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 12341 Handle<String> name = isolate->factory()->NumberToString(number); | 12382 Handle<String> name = isolate->factory()->NumberToString(number); |
| 12342 Handle<Object> args[1] = { name }; | 12383 Handle<Object> args[1] = { name }; |
| 12343 Handle<Object> error = | 12384 Handle<Object> error = |
| 12344 isolate->factory()->NewTypeError("object_not_extensible", | 12385 isolate->factory()->NewTypeError("object_not_extensible", |
| 12345 HandleVector(args, 1)); | 12386 HandleVector(args, 1)); |
| 12346 return isolate->Throw(*error); | 12387 isolate->Throw(*error); |
| 12388 return Handle<Object>(); |
| 12347 } | 12389 } |
| 12348 } | 12390 } |
| 12349 FixedArrayBase* new_dictionary; | 12391 |
| 12350 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); | 12392 PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); |
| 12351 MaybeObject* maybe = dictionary->AddNumberEntry(index, *value, details); | 12393 Handle<SeededNumberDictionary> new_dictionary = |
| 12352 if (!maybe->To(&new_dictionary)) return maybe; | 12394 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, |
| 12353 if (*dictionary != SeededNumberDictionary::cast(new_dictionary)) { | 12395 details); |
| 12396 if (*dictionary != *new_dictionary) { |
| 12354 if (is_arguments) { | 12397 if (is_arguments) { |
| 12355 elements->set(1, new_dictionary); | 12398 elements->set(1, *new_dictionary); |
| 12356 } else { | 12399 } else { |
| 12357 self->set_elements(new_dictionary); | 12400 object->set_elements(*new_dictionary); |
| 12358 } | 12401 } |
| 12359 dictionary = | 12402 dictionary = new_dictionary; |
| 12360 handle(SeededNumberDictionary::cast(new_dictionary), isolate); | |
| 12361 } | 12403 } |
| 12362 } | 12404 } |
| 12363 | 12405 |
| 12364 // Update the array length if this JSObject is an array. | 12406 // Update the array length if this JSObject is an array. |
| 12365 if (self->IsJSArray()) { | 12407 if (object->IsJSArray()) { |
| 12366 MaybeObject* result = | 12408 JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray>::cast(object), index, |
| 12367 JSArray::cast(*self)->JSArrayUpdateLengthFromIndex(index, *value); | 12409 value); |
| 12368 if (result->IsFailure()) return result; | |
| 12369 } | 12410 } |
| 12370 | 12411 |
| 12371 // Attempt to put this object back in fast case. | 12412 // Attempt to put this object back in fast case. |
| 12372 if (self->ShouldConvertToFastElements()) { | 12413 if (object->ShouldConvertToFastElements()) { |
| 12373 uint32_t new_length = 0; | 12414 uint32_t new_length = 0; |
| 12374 if (self->IsJSArray()) { | 12415 if (object->IsJSArray()) { |
| 12375 CHECK(JSArray::cast(*self)->length()->ToArrayIndex(&new_length)); | 12416 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&new_length)); |
| 12376 } else { | 12417 } else { |
| 12377 new_length = dictionary->max_number_key() + 1; | 12418 new_length = dictionary->max_number_key() + 1; |
| 12378 } | 12419 } |
| 12379 SetFastElementsCapacitySmiMode smi_mode = FLAG_smi_only_arrays | 12420 SetFastElementsCapacitySmiMode smi_mode = FLAG_smi_only_arrays |
| 12380 ? kAllowSmiElements | 12421 ? kAllowSmiElements |
| 12381 : kDontAllowSmiElements; | 12422 : kDontAllowSmiElements; |
| 12382 bool has_smi_only_elements = false; | 12423 bool has_smi_only_elements = false; |
| 12383 bool should_convert_to_fast_double_elements = | 12424 bool should_convert_to_fast_double_elements = |
| 12384 self->ShouldConvertToFastDoubleElements(&has_smi_only_elements); | 12425 object->ShouldConvertToFastDoubleElements(&has_smi_only_elements); |
| 12385 if (has_smi_only_elements) { | 12426 if (has_smi_only_elements) { |
| 12386 smi_mode = kForceSmiElements; | 12427 smi_mode = kForceSmiElements; |
| 12387 } | 12428 } |
| 12388 MaybeObject* result = should_convert_to_fast_double_elements | 12429 |
| 12389 ? self->SetFastDoubleElementsCapacityAndLength(new_length, new_length) | 12430 if (should_convert_to_fast_double_elements) { |
| 12390 : self->SetFastElementsCapacityAndLength( | 12431 SetFastDoubleElementsCapacityAndLength(object, new_length, new_length); |
| 12391 new_length, new_length, smi_mode); | 12432 } else { |
| 12392 self->ValidateElements(); | 12433 SetFastElementsCapacityAndLength(object, new_length, new_length, |
| 12393 if (result->IsFailure()) return result; | 12434 smi_mode); |
| 12435 } |
| 12436 object->ValidateElements(); |
| 12394 #ifdef DEBUG | 12437 #ifdef DEBUG |
| 12395 if (FLAG_trace_normalization) { | 12438 if (FLAG_trace_normalization) { |
| 12396 PrintF("Object elements are fast case again:\n"); | 12439 PrintF("Object elements are fast case again:\n"); |
| 12397 Print(); | 12440 object->Print(); |
| 12398 } | 12441 } |
| 12399 #endif | 12442 #endif |
| 12400 } | 12443 } |
| 12401 return *value; | 12444 return value; |
| 12402 } | 12445 } |
| 12403 | 12446 |
| 12404 | 12447 Handle<Object> JSObject::SetFastDoubleElement( |
| 12405 MUST_USE_RESULT MaybeObject* JSObject::SetFastDoubleElement( | 12448 Handle<JSObject> object, |
| 12406 uint32_t index, | 12449 uint32_t index, |
| 12407 Object* value, | 12450 Handle<Object> value, |
| 12408 StrictModeFlag strict_mode, | 12451 StrictModeFlag strict_mode, |
| 12409 bool check_prototype) { | 12452 bool check_prototype) { |
| 12410 ASSERT(HasFastDoubleElements()); | 12453 ASSERT(object->HasFastDoubleElements()); |
| 12411 | 12454 |
| 12412 FixedArrayBase* base_elms = FixedArrayBase::cast(elements()); | 12455 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements())); |
| 12413 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); | 12456 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); |
| 12414 | 12457 |
| 12415 // If storing to an element that isn't in the array, pass the store request | 12458 // If storing to an element that isn't in the array, pass the store request |
| 12416 // up the prototype chain before storing in the receiver's elements. | 12459 // up the prototype chain before storing in the receiver's elements. |
| 12417 if (check_prototype && | 12460 if (check_prototype && |
| 12418 (index >= elms_length || | 12461 (index >= elms_length || |
| 12419 FixedDoubleArray::cast(base_elms)->is_the_hole(index))) { | 12462 Handle<FixedDoubleArray>::cast(base_elms)->is_the_hole(index))) { |
| 12420 bool found; | 12463 bool found; |
| 12421 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, | 12464 Handle<Object> result = SetElementWithCallbackSetterInPrototypes(object, |
| 12422 value, | 12465 index, value, &found, strict_mode); |
| 12423 &found, | |
| 12424 strict_mode); | |
| 12425 if (found) return result; | 12466 if (found) return result; |
| 12426 } | 12467 } |
| 12427 | 12468 |
| 12428 // If the value object is not a heap number, switch to fast elements and try | 12469 // If the value object is not a heap number, switch to fast elements and try |
| 12429 // again. | 12470 // again. |
| 12430 bool value_is_smi = value->IsSmi(); | 12471 bool value_is_smi = value->IsSmi(); |
| 12431 bool introduces_holes = true; | 12472 bool introduces_holes = true; |
| 12432 uint32_t length = elms_length; | 12473 uint32_t length = elms_length; |
| 12433 if (IsJSArray()) { | 12474 if (object->IsJSArray()) { |
| 12434 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); | 12475 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayIndex(&length)); |
| 12435 introduces_holes = index > length; | 12476 introduces_holes = index > length; |
| 12436 } else { | 12477 } else { |
| 12437 introduces_holes = index >= elms_length; | 12478 introduces_holes = index >= elms_length; |
| 12438 } | 12479 } |
| 12439 | 12480 |
| 12440 if (!value->IsNumber()) { | 12481 if (!value->IsNumber()) { |
| 12441 MaybeObject* maybe_obj = SetFastElementsCapacityAndLength( | 12482 SetFastElementsCapacityAndLength(object, elms_length, length, |
| 12442 elms_length, | 12483 kDontAllowSmiElements); |
| 12443 length, | 12484 Handle<Object> result = SetFastElement(object, index, value, strict_mode, |
| 12444 kDontAllowSmiElements); | 12485 check_prototype); |
| 12445 if (maybe_obj->IsFailure()) return maybe_obj; | 12486 RETURN_IF_EMPTY_HANDLE_VALUE(object->GetIsolate(), result, |
| 12446 maybe_obj = SetFastElement(index, value, strict_mode, check_prototype); | 12487 Handle<Object>()); |
| 12447 if (maybe_obj->IsFailure()) return maybe_obj; | 12488 object->ValidateElements(); |
| 12448 ValidateElements(); | 12489 return result; |
| 12449 return maybe_obj; | |
| 12450 } | 12490 } |
| 12451 | 12491 |
| 12452 double double_value = value_is_smi | 12492 double double_value = value_is_smi |
| 12453 ? static_cast<double>(Smi::cast(value)->value()) | 12493 ? static_cast<double>(Handle<Smi>::cast(value)->value()) |
| 12454 : HeapNumber::cast(value)->value(); | 12494 : Handle<HeapNumber>::cast(value)->value(); |
| 12455 | 12495 |
| 12456 // If the array is growing, and it's not growth by a single element at the | 12496 // If the array is growing, and it's not growth by a single element at the |
| 12457 // end, make sure that the ElementsKind is HOLEY. | 12497 // end, make sure that the ElementsKind is HOLEY. |
| 12458 ElementsKind elements_kind = GetElementsKind(); | 12498 ElementsKind elements_kind = object->GetElementsKind(); |
| 12459 if (introduces_holes && !IsFastHoleyElementsKind(elements_kind)) { | 12499 if (introduces_holes && !IsFastHoleyElementsKind(elements_kind)) { |
| 12460 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); | 12500 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); |
| 12461 MaybeObject* maybe = TransitionElementsKind(transitioned_kind); | 12501 TransitionElementsKind(object, transitioned_kind); |
| 12462 if (maybe->IsFailure()) return maybe; | |
| 12463 } | 12502 } |
| 12464 | 12503 |
| 12465 // Check whether there is extra space in the fixed array. | 12504 // Check whether there is extra space in the fixed array. |
| 12466 if (index < elms_length) { | 12505 if (index < elms_length) { |
| 12467 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); | 12506 Handle<FixedDoubleArray> elms(FixedDoubleArray::cast(object->elements())); |
| 12468 elms->set(index, double_value); | 12507 elms->set(index, double_value); |
| 12469 if (IsJSArray()) { | 12508 if (object->IsJSArray()) { |
| 12470 // Update the length of the array if needed. | 12509 // Update the length of the array if needed. |
| 12471 uint32_t array_length = 0; | 12510 uint32_t array_length = 0; |
| 12472 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); | 12511 CHECK( |
| 12512 Handle<JSArray>::cast(object)->length()->ToArrayIndex(&array_length)); |
| 12473 if (index >= array_length) { | 12513 if (index >= array_length) { |
| 12474 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); | 12514 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(index + 1)); |
| 12475 } | 12515 } |
| 12476 } | 12516 } |
| 12477 return value; | 12517 return value; |
| 12478 } | 12518 } |
| 12479 | 12519 |
| 12480 // Allow gap in fast case. | 12520 // Allow gap in fast case. |
| 12481 if ((index - elms_length) < kMaxGap) { | 12521 if ((index - elms_length) < kMaxGap) { |
| 12482 // Try allocating extra space. | 12522 // Try allocating extra space. |
| 12483 int new_capacity = NewElementsCapacity(index+1); | 12523 int new_capacity = NewElementsCapacity(index+1); |
| 12484 if (!ShouldConvertToSlowElements(new_capacity)) { | 12524 if (!object->ShouldConvertToSlowElements(new_capacity)) { |
| 12485 ASSERT(static_cast<uint32_t>(new_capacity) > index); | 12525 ASSERT(static_cast<uint32_t>(new_capacity) > index); |
| 12486 MaybeObject* maybe_obj = | 12526 SetFastDoubleElementsCapacityAndLength(object, new_capacity, index + 1); |
| 12487 SetFastDoubleElementsCapacityAndLength(new_capacity, index + 1); | 12527 FixedDoubleArray::cast(object->elements())->set(index, double_value); |
| 12488 if (maybe_obj->IsFailure()) return maybe_obj; | 12528 object->ValidateElements(); |
| 12489 FixedDoubleArray::cast(elements())->set(index, double_value); | |
| 12490 ValidateElements(); | |
| 12491 return value; | 12529 return value; |
| 12492 } | 12530 } |
| 12493 } | 12531 } |
| 12494 | 12532 |
| 12495 // Otherwise default to slow case. | 12533 // Otherwise default to slow case. |
| 12496 ASSERT(HasFastDoubleElements()); | 12534 ASSERT(object->HasFastDoubleElements()); |
| 12497 ASSERT(map()->has_fast_double_elements()); | 12535 ASSERT(object->map()->has_fast_double_elements()); |
| 12498 ASSERT(elements()->IsFixedDoubleArray()); | 12536 ASSERT(object->elements()->IsFixedDoubleArray()); |
| 12499 Object* obj; | 12537 |
| 12500 { MaybeObject* maybe_obj = NormalizeElements(); | 12538 NormalizeElements(object); |
| 12501 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 12539 ASSERT(object->HasDictionaryElements()); |
| 12502 } | 12540 return SetElement(object, index, value, NONE, strict_mode, check_prototype); |
| 12503 ASSERT(HasDictionaryElements()); | |
| 12504 return SetElement(index, value, NONE, strict_mode, check_prototype); | |
| 12505 } | 12541 } |
| 12506 | 12542 |
| 12507 | 12543 |
| 12508 Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, | 12544 Handle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, |
| 12509 uint32_t index, | 12545 uint32_t index, |
| 12510 Handle<Object> value, | 12546 Handle<Object> value, |
| 12511 PropertyAttributes attributes, | 12547 PropertyAttributes attributes, |
| 12512 StrictModeFlag strict_mode) { | 12548 StrictModeFlag strict_mode) { |
| 12513 if (object->IsJSProxy()) { | 12549 if (object->IsJSProxy()) { |
| 12514 return JSProxy::SetElementWithHandler( | 12550 return JSProxy::SetElementWithHandler( |
| 12515 Handle<JSProxy>::cast(object), object, index, value, strict_mode); | 12551 Handle<JSProxy>::cast(object), object, index, value, strict_mode); |
| 12516 } | 12552 } |
| 12517 return JSObject::SetElement( | 12553 return JSObject::SetElement( |
| 12518 Handle<JSObject>::cast(object), index, value, attributes, strict_mode); | 12554 Handle<JSObject>::cast(object), index, value, attributes, strict_mode); |
| 12519 } | 12555 } |
| 12520 | 12556 |
| 12521 | 12557 |
| 12522 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object, | 12558 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object, |
| 12523 uint32_t index, | 12559 uint32_t index, |
| 12524 Handle<Object> value, | 12560 Handle<Object> value, |
| 12525 StrictModeFlag strict_mode) { | 12561 StrictModeFlag strict_mode) { |
| 12526 ASSERT(!object->HasExternalArrayElements()); | 12562 ASSERT(!object->HasExternalArrayElements()); |
| 12527 CALL_HEAP_FUNCTION( | 12563 return JSObject::SetElement(object, index, value, NONE, strict_mode, false); |
| 12528 object->GetIsolate(), | |
| 12529 object->SetElement(index, *value, NONE, strict_mode, false), | |
| 12530 Object); | |
| 12531 } | 12564 } |
| 12532 | 12565 |
| 12533 | 12566 |
| 12534 Handle<Object> JSObject::SetElement(Handle<JSObject> object, | 12567 Handle<Object> JSObject::SetElement(Handle<JSObject> object, |
| 12535 uint32_t index, | 12568 uint32_t index, |
| 12536 Handle<Object> value, | 12569 Handle<Object> value, |
| 12537 PropertyAttributes attr, | 12570 PropertyAttributes attributes, |
| 12538 StrictModeFlag strict_mode, | 12571 StrictModeFlag strict_mode, |
| 12539 bool check_prototype, | 12572 bool check_prototype, |
| 12540 SetPropertyMode set_mode) { | 12573 SetPropertyMode set_mode) { |
| 12574 Isolate* isolate = object->GetIsolate(); |
| 12575 |
| 12541 if (object->HasExternalArrayElements()) { | 12576 if (object->HasExternalArrayElements()) { |
| 12542 if (!value->IsNumber() && !value->IsUndefined()) { | 12577 if (!value->IsNumber() && !value->IsUndefined()) { |
| 12543 bool has_exception; | 12578 bool has_exception; |
| 12544 Handle<Object> number = | 12579 Handle<Object> number = |
| 12545 Execution::ToNumber(object->GetIsolate(), value, &has_exception); | 12580 Execution::ToNumber(isolate, value, &has_exception); |
| 12546 if (has_exception) return Handle<Object>(); | 12581 if (has_exception) return Handle<Object>(); |
| 12547 value = number; | 12582 value = number; |
| 12548 } | 12583 } |
| 12549 } | 12584 } |
| 12550 CALL_HEAP_FUNCTION( | |
| 12551 object->GetIsolate(), | |
| 12552 object->SetElement(index, *value, attr, strict_mode, check_prototype, | |
| 12553 set_mode), | |
| 12554 Object); | |
| 12555 } | |
| 12556 | |
| 12557 | |
| 12558 MaybeObject* JSObject::SetElement(uint32_t index, | |
| 12559 Object* value_raw, | |
| 12560 PropertyAttributes attributes, | |
| 12561 StrictModeFlag strict_mode, | |
| 12562 bool check_prototype, | |
| 12563 SetPropertyMode set_mode) { | |
| 12564 Isolate* isolate = GetIsolate(); | |
| 12565 | 12585 |
| 12566 // Check access rights if needed. | 12586 // Check access rights if needed. |
| 12567 if (IsAccessCheckNeeded()) { | 12587 if (object->IsAccessCheckNeeded()) { |
| 12568 if (!isolate->MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 12588 if (!isolate->MayIndexedAccess(*object, index, v8::ACCESS_SET)) { |
| 12569 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 12589 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); |
| 12570 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 12590 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 12571 return value_raw; | 12591 return value; |
| 12572 } | 12592 } |
| 12573 } | 12593 } |
| 12574 | 12594 |
| 12575 if (IsJSGlobalProxy()) { | 12595 if (object->IsJSGlobalProxy()) { |
| 12576 Object* proto = GetPrototype(); | 12596 Handle<Object> proto(object->GetPrototype(), isolate); |
| 12577 if (proto->IsNull()) return value_raw; | 12597 if (proto->IsNull()) return value; |
| 12578 ASSERT(proto->IsJSGlobalObject()); | 12598 ASSERT(proto->IsJSGlobalObject()); |
| 12579 return JSObject::cast(proto)->SetElement(index, | 12599 return SetElement(Handle<JSObject>::cast(proto), index, value, attributes, |
| 12580 value_raw, | 12600 strict_mode, |
| 12581 attributes, | 12601 check_prototype, |
| 12582 strict_mode, | 12602 set_mode); |
| 12583 check_prototype, | |
| 12584 set_mode); | |
| 12585 } | 12603 } |
| 12586 | 12604 |
| 12587 // Don't allow element properties to be redefined for external arrays. | 12605 // Don't allow element properties to be redefined for external arrays. |
| 12588 if (HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { | 12606 if (object->HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) { |
| 12589 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12607 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| 12590 Handle<Object> args[] = { handle(this, isolate), number }; | 12608 Handle<Object> args[] = { object, number }; |
| 12591 Handle<Object> error = isolate->factory()->NewTypeError( | 12609 Handle<Object> error = isolate->factory()->NewTypeError( |
| 12592 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); | 12610 "redef_external_array_element", HandleVector(args, ARRAY_SIZE(args))); |
| 12593 return isolate->Throw(*error); | 12611 isolate->Throw(*error); |
| 12612 return Handle<Object>(); |
| 12594 } | 12613 } |
| 12595 | 12614 |
| 12596 // Normalize the elements to enable attributes on the property. | 12615 // Normalize the elements to enable attributes on the property. |
| 12597 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { | 12616 if ((attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) { |
| 12598 SeededNumberDictionary* dictionary; | 12617 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
| 12599 MaybeObject* maybe_object = NormalizeElements(); | |
| 12600 if (!maybe_object->To(&dictionary)) return maybe_object; | |
| 12601 // Make sure that we never go back to fast case. | 12618 // Make sure that we never go back to fast case. |
| 12602 dictionary->set_requires_slow_elements(); | 12619 dictionary->set_requires_slow_elements(); |
| 12603 } | 12620 } |
| 12604 | 12621 |
| 12605 if (!(FLAG_harmony_observation && map()->is_observed())) { | 12622 if (!(FLAG_harmony_observation && object->map()->is_observed())) { |
| 12606 return HasIndexedInterceptor() | 12623 return object->HasIndexedInterceptor() |
| 12607 ? SetElementWithInterceptor( | 12624 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, |
| 12608 index, value_raw, attributes, strict_mode, check_prototype, set_mode) | 12625 check_prototype, |
| 12609 : SetElementWithoutInterceptor( | 12626 set_mode) |
| 12610 index, value_raw, attributes, strict_mode, check_prototype, set_mode); | 12627 : SetElementWithoutInterceptor(object, index, value, attributes, |
| 12611 } | 12628 strict_mode, |
| 12612 | 12629 check_prototype, |
| 12613 // From here on, everything has to be handlified. | 12630 set_mode); |
| 12614 Handle<JSObject> self(this); | 12631 } |
| 12615 Handle<Object> value(value_raw, isolate); | 12632 |
| 12616 PropertyAttributes old_attributes = self->GetLocalElementAttribute(index); | 12633 PropertyAttributes old_attributes = object->GetLocalElementAttribute(index); |
| 12617 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 12634 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| 12618 Handle<Object> old_length_handle; | 12635 Handle<Object> old_length_handle; |
| 12619 Handle<Object> new_length_handle; | 12636 Handle<Object> new_length_handle; |
| 12620 | 12637 |
| 12621 if (old_attributes != ABSENT) { | 12638 if (old_attributes != ABSENT) { |
| 12622 if (self->GetLocalElementAccessorPair(index) == NULL) | 12639 if (object->GetLocalElementAccessorPair(index) == NULL) |
| 12623 old_value = Object::GetElement(isolate, self, index); | 12640 old_value = Object::GetElement(isolate, object, index); |
| 12624 } else if (self->IsJSArray()) { | 12641 } else if (object->IsJSArray()) { |
| 12625 // Store old array length in case adding an element grows the array. | 12642 // Store old array length in case adding an element grows the array. |
| 12626 old_length_handle = handle(Handle<JSArray>::cast(self)->length(), isolate); | 12643 old_length_handle = handle(Handle<JSArray>::cast(object)->length(), |
| 12644 isolate); |
| 12627 } | 12645 } |
| 12628 | 12646 |
| 12629 // Check for lookup interceptor | 12647 // Check for lookup interceptor |
| 12630 MaybeObject* result = self->HasIndexedInterceptor() | 12648 Handle<Object> result = object->HasIndexedInterceptor() |
| 12631 ? self->SetElementWithInterceptor( | 12649 ? SetElementWithInterceptor(object, index, value, attributes, strict_mode, |
| 12632 index, *value, attributes, strict_mode, check_prototype, set_mode) | 12650 check_prototype, |
| 12633 : self->SetElementWithoutInterceptor( | 12651 set_mode) |
| 12634 index, *value, attributes, strict_mode, check_prototype, set_mode); | 12652 : SetElementWithoutInterceptor(object, index, value, attributes, |
| 12635 | 12653 strict_mode, |
| 12636 Handle<Object> hresult; | 12654 check_prototype, |
| 12637 if (!result->ToHandle(&hresult, isolate)) return result; | 12655 set_mode); |
| 12656 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<Object>()); |
| 12638 | 12657 |
| 12639 Handle<String> name = isolate->factory()->Uint32ToString(index); | 12658 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| 12640 PropertyAttributes new_attributes = self->GetLocalElementAttribute(index); | 12659 PropertyAttributes new_attributes = object->GetLocalElementAttribute(index); |
| 12641 if (old_attributes == ABSENT) { | 12660 if (old_attributes == ABSENT) { |
| 12642 if (self->IsJSArray() && | 12661 if (object->IsJSArray() && |
| 12643 !old_length_handle->SameValue(Handle<JSArray>::cast(self)->length())) { | 12662 !old_length_handle->SameValue( |
| 12644 new_length_handle = handle(Handle<JSArray>::cast(self)->length(), | 12663 Handle<JSArray>::cast(object)->length())) { |
| 12664 new_length_handle = handle(Handle<JSArray>::cast(object)->length(), |
| 12645 isolate); | 12665 isolate); |
| 12646 uint32_t old_length = 0; | 12666 uint32_t old_length = 0; |
| 12647 uint32_t new_length = 0; | 12667 uint32_t new_length = 0; |
| 12648 CHECK(old_length_handle->ToArrayIndex(&old_length)); | 12668 CHECK(old_length_handle->ToArrayIndex(&old_length)); |
| 12649 CHECK(new_length_handle->ToArrayIndex(&new_length)); | 12669 CHECK(new_length_handle->ToArrayIndex(&new_length)); |
| 12650 | 12670 |
| 12651 BeginPerformSplice(Handle<JSArray>::cast(self)); | 12671 BeginPerformSplice(Handle<JSArray>::cast(object)); |
| 12652 EnqueueChangeRecord(self, "add", name, old_value); | 12672 EnqueueChangeRecord(object, "add", name, old_value); |
| 12653 EnqueueChangeRecord(self, "update", isolate->factory()->length_string(), | 12673 EnqueueChangeRecord(object, "update", isolate->factory()->length_string(), |
| 12654 old_length_handle); | 12674 old_length_handle); |
| 12655 EndPerformSplice(Handle<JSArray>::cast(self)); | 12675 EndPerformSplice(Handle<JSArray>::cast(object)); |
| 12656 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 12676 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
| 12657 EnqueueSpliceRecord(Handle<JSArray>::cast(self), old_length, deleted, | 12677 EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length, deleted, |
| 12658 new_length - old_length); | 12678 new_length - old_length); |
| 12659 } else { | 12679 } else { |
| 12660 EnqueueChangeRecord(self, "add", name, old_value); | 12680 EnqueueChangeRecord(object, "add", name, old_value); |
| 12661 } | 12681 } |
| 12662 } else if (old_value->IsTheHole()) { | 12682 } else if (old_value->IsTheHole()) { |
| 12663 EnqueueChangeRecord(self, "reconfigure", name, old_value); | 12683 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
| 12664 } else { | 12684 } else { |
| 12665 Handle<Object> new_value = Object::GetElement(isolate, self, index); | 12685 Handle<Object> new_value = Object::GetElement(isolate, object, index); |
| 12666 bool value_changed = !old_value->SameValue(*new_value); | 12686 bool value_changed = !old_value->SameValue(*new_value); |
| 12667 if (old_attributes != new_attributes) { | 12687 if (old_attributes != new_attributes) { |
| 12668 if (!value_changed) old_value = isolate->factory()->the_hole_value(); | 12688 if (!value_changed) old_value = isolate->factory()->the_hole_value(); |
| 12669 EnqueueChangeRecord(self, "reconfigure", name, old_value); | 12689 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
| 12670 } else if (value_changed) { | 12690 } else if (value_changed) { |
| 12671 EnqueueChangeRecord(self, "update", name, old_value); | 12691 EnqueueChangeRecord(object, "update", name, old_value); |
| 12672 } | 12692 } |
| 12673 } | 12693 } |
| 12674 | 12694 |
| 12675 return *hresult; | 12695 return result; |
| 12676 } | 12696 } |
| 12677 | 12697 |
| 12678 | 12698 |
| 12679 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, | 12699 Handle<Object> JSObject::SetElementWithoutInterceptor( |
| 12680 Object* value, | 12700 Handle<JSObject> object, |
| 12681 PropertyAttributes attr, | 12701 uint32_t index, |
| 12682 StrictModeFlag strict_mode, | 12702 Handle<Object> value, |
| 12683 bool check_prototype, | 12703 PropertyAttributes attributes, |
| 12684 SetPropertyMode set_mode) { | 12704 StrictModeFlag strict_mode, |
| 12685 ASSERT(HasDictionaryElements() || | 12705 bool check_prototype, |
| 12686 HasDictionaryArgumentsElements() || | 12706 SetPropertyMode set_mode) { |
| 12687 (attr & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); | 12707 ASSERT(object->HasDictionaryElements() || |
| 12688 Isolate* isolate = GetIsolate(); | 12708 object->HasDictionaryArgumentsElements() || |
| 12709 (attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); |
| 12710 Isolate* isolate = object->GetIsolate(); |
| 12689 if (FLAG_trace_external_array_abuse && | 12711 if (FLAG_trace_external_array_abuse && |
| 12690 IsExternalArrayElementsKind(GetElementsKind())) { | 12712 IsExternalArrayElementsKind(object->GetElementsKind())) { |
| 12691 CheckArrayAbuse(this, "external elements write", index); | 12713 CheckArrayAbuse(*object, "external elements write", index); |
| 12692 } | 12714 } |
| 12693 if (FLAG_trace_js_array_abuse && | 12715 if (FLAG_trace_js_array_abuse && |
| 12694 !IsExternalArrayElementsKind(GetElementsKind())) { | 12716 !IsExternalArrayElementsKind(object->GetElementsKind())) { |
| 12695 if (IsJSArray()) { | 12717 if (object->IsJSArray()) { |
| 12696 CheckArrayAbuse(this, "elements write", index, true); | 12718 CheckArrayAbuse(*object, "elements write", index, true); |
| 12697 } | 12719 } |
| 12698 } | 12720 } |
| 12699 switch (GetElementsKind()) { | 12721 switch (object->GetElementsKind()) { |
| 12700 case FAST_SMI_ELEMENTS: | 12722 case FAST_SMI_ELEMENTS: |
| 12701 case FAST_ELEMENTS: | 12723 case FAST_ELEMENTS: |
| 12702 case FAST_HOLEY_SMI_ELEMENTS: | 12724 case FAST_HOLEY_SMI_ELEMENTS: |
| 12703 case FAST_HOLEY_ELEMENTS: | 12725 case FAST_HOLEY_ELEMENTS: |
| 12704 return SetFastElement(index, value, strict_mode, check_prototype); | 12726 return SetFastElement(object, index, value, strict_mode, check_prototype); |
| 12705 case FAST_DOUBLE_ELEMENTS: | 12727 case FAST_DOUBLE_ELEMENTS: |
| 12706 case FAST_HOLEY_DOUBLE_ELEMENTS: | 12728 case FAST_HOLEY_DOUBLE_ELEMENTS: |
| 12707 return SetFastDoubleElement(index, value, strict_mode, check_prototype); | 12729 return SetFastDoubleElement(object, index, value, strict_mode, |
| 12730 check_prototype); |
| 12708 case EXTERNAL_PIXEL_ELEMENTS: { | 12731 case EXTERNAL_PIXEL_ELEMENTS: { |
| 12709 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); | 12732 ExternalPixelArray* pixels = ExternalPixelArray::cast(object->elements()); |
| 12710 return pixels->SetValue(index, value); | 12733 return handle(pixels->SetValue(index, *value), isolate); |
| 12711 } | 12734 } |
| 12712 case EXTERNAL_BYTE_ELEMENTS: { | 12735 case EXTERNAL_BYTE_ELEMENTS: { |
| 12713 ExternalByteArray* array = ExternalByteArray::cast(elements()); | 12736 Handle<ExternalByteArray> array( |
| 12714 return array->SetValue(index, value); | 12737 ExternalByteArray::cast(object->elements())); |
| 12738 return ExternalByteArray::SetValue(array, index, value); |
| 12715 } | 12739 } |
| 12716 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { | 12740 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { |
| 12717 ExternalUnsignedByteArray* array = | 12741 Handle<ExternalUnsignedByteArray> array( |
| 12718 ExternalUnsignedByteArray::cast(elements()); | 12742 ExternalUnsignedByteArray::cast(object->elements())); |
| 12719 return array->SetValue(index, value); | 12743 return ExternalUnsignedByteArray::SetValue(array, index, value); |
| 12720 } | 12744 } |
| 12721 case EXTERNAL_SHORT_ELEMENTS: { | 12745 case EXTERNAL_SHORT_ELEMENTS: { |
| 12722 ExternalShortArray* array = ExternalShortArray::cast(elements()); | 12746 Handle<ExternalShortArray> array(ExternalShortArray::cast( |
| 12723 return array->SetValue(index, value); | 12747 object->elements())); |
| 12748 return ExternalShortArray::SetValue(array, index, value); |
| 12724 } | 12749 } |
| 12725 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { | 12750 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: { |
| 12726 ExternalUnsignedShortArray* array = | 12751 Handle<ExternalUnsignedShortArray> array( |
| 12727 ExternalUnsignedShortArray::cast(elements()); | 12752 ExternalUnsignedShortArray::cast(object->elements())); |
| 12728 return array->SetValue(index, value); | 12753 return ExternalUnsignedShortArray::SetValue(array, index, value); |
| 12729 } | 12754 } |
| 12730 case EXTERNAL_INT_ELEMENTS: { | 12755 case EXTERNAL_INT_ELEMENTS: { |
| 12731 ExternalIntArray* array = ExternalIntArray::cast(elements()); | 12756 Handle<ExternalIntArray> array( |
| 12732 return array->SetValue(index, value); | 12757 ExternalIntArray::cast(object->elements())); |
| 12758 return ExternalIntArray::SetValue(array, index, value); |
| 12733 } | 12759 } |
| 12734 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { | 12760 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { |
| 12735 ExternalUnsignedIntArray* array = | 12761 Handle<ExternalUnsignedIntArray> array( |
| 12736 ExternalUnsignedIntArray::cast(elements()); | 12762 ExternalUnsignedIntArray::cast(object->elements())); |
| 12737 return array->SetValue(index, value); | 12763 return ExternalUnsignedIntArray::SetValue(array, index, value); |
| 12738 } | 12764 } |
| 12739 case EXTERNAL_FLOAT_ELEMENTS: { | 12765 case EXTERNAL_FLOAT_ELEMENTS: { |
| 12740 ExternalFloatArray* array = ExternalFloatArray::cast(elements()); | 12766 Handle<ExternalFloatArray> array( |
| 12741 return array->SetValue(index, value); | 12767 ExternalFloatArray::cast(object->elements())); |
| 12768 return ExternalFloatArray::SetValue(array, index, value); |
| 12742 } | 12769 } |
| 12743 case EXTERNAL_DOUBLE_ELEMENTS: { | 12770 case EXTERNAL_DOUBLE_ELEMENTS: { |
| 12744 ExternalDoubleArray* array = ExternalDoubleArray::cast(elements()); | 12771 Handle<ExternalDoubleArray> array( |
| 12745 return array->SetValue(index, value); | 12772 ExternalDoubleArray::cast(object->elements())); |
| 12773 return ExternalDoubleArray::SetValue(array, index, value); |
| 12746 } | 12774 } |
| 12747 case DICTIONARY_ELEMENTS: | 12775 case DICTIONARY_ELEMENTS: |
| 12748 return SetDictionaryElement(index, value, attr, strict_mode, | 12776 return SetDictionaryElement(object, index, value, attributes, strict_mode, |
| 12749 check_prototype, set_mode); | 12777 check_prototype, |
| 12778 set_mode); |
| 12750 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 12779 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 12751 FixedArray* parameter_map = FixedArray::cast(elements()); | 12780 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); |
| 12752 uint32_t length = parameter_map->length(); | 12781 uint32_t length = parameter_map->length(); |
| 12753 Object* probe = | 12782 Handle<Object> probe = index < length - 2 ? |
| 12754 (index < length - 2) ? parameter_map->get(index + 2) : NULL; | 12783 Handle<Object>(parameter_map->get(index + 2), isolate) : |
| 12755 if (probe != NULL && !probe->IsTheHole()) { | 12784 Handle<Object>(); |
| 12756 Context* context = Context::cast(parameter_map->get(0)); | 12785 if (!probe.is_null() && !probe->IsTheHole()) { |
| 12757 int context_index = Smi::cast(probe)->value(); | 12786 Handle<Context> context(Context::cast(parameter_map->get(0))); |
| 12787 int context_index = Handle<Smi>::cast(probe)->value(); |
| 12758 ASSERT(!context->get(context_index)->IsTheHole()); | 12788 ASSERT(!context->get(context_index)->IsTheHole()); |
| 12759 context->set(context_index, value); | 12789 context->set(context_index, *value); |
| 12760 // Redefining attributes of an aliased element destroys fast aliasing. | 12790 // Redefining attributes of an aliased element destroys fast aliasing. |
| 12761 if (set_mode == SET_PROPERTY || attr == NONE) return value; | 12791 if (set_mode == SET_PROPERTY || attributes == NONE) return value; |
| 12762 parameter_map->set_the_hole(index + 2); | 12792 parameter_map->set_the_hole(index + 2); |
| 12763 // For elements that are still writable we re-establish slow aliasing. | 12793 // For elements that are still writable we re-establish slow aliasing. |
| 12764 if ((attr & READ_ONLY) == 0) { | 12794 if ((attributes & READ_ONLY) == 0) { |
| 12765 MaybeObject* maybe_entry = | 12795 value = Handle<Object>::cast( |
| 12766 isolate->heap()->AllocateAliasedArgumentsEntry(context_index); | 12796 isolate->factory()->NewAliasedArgumentsEntry(context_index)); |
| 12767 if (!maybe_entry->ToObject(&value)) return maybe_entry; | |
| 12768 } | 12797 } |
| 12769 } | 12798 } |
| 12770 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 12799 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); |
| 12771 if (arguments->IsDictionary()) { | 12800 if (arguments->IsDictionary()) { |
| 12772 return SetDictionaryElement(index, value, attr, strict_mode, | 12801 return SetDictionaryElement(object, index, value, attributes, |
| 12773 check_prototype, set_mode); | 12802 strict_mode, |
| 12803 check_prototype, |
| 12804 set_mode); |
| 12774 } else { | 12805 } else { |
| 12775 return SetFastElement(index, value, strict_mode, check_prototype); | 12806 return SetFastElement(object, index, value, strict_mode, |
| 12807 check_prototype); |
| 12776 } | 12808 } |
| 12777 } | 12809 } |
| 12778 } | 12810 } |
| 12779 // All possible cases have been handled above. Add a return to avoid the | 12811 // All possible cases have been handled above. Add a return to avoid the |
| 12780 // complaints from the compiler. | 12812 // complaints from the compiler. |
| 12781 UNREACHABLE(); | 12813 UNREACHABLE(); |
| 12782 return isolate->heap()->null_value(); | 12814 return isolate->factory()->null_value(); |
| 12783 } | 12815 } |
| 12784 | 12816 |
| 12785 | 12817 |
| 12786 void JSObject::TransitionElementsKind(Handle<JSObject> object, | 12818 void JSObject::TransitionElementsKind(Handle<JSObject> object, |
| 12787 ElementsKind to_kind) { | 12819 ElementsKind to_kind) { |
| 12788 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), | 12820 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), |
| 12789 object->TransitionElementsKind(to_kind)); | 12821 object->TransitionElementsKind(to_kind)); |
| 12790 } | 12822 } |
| 12791 | 12823 |
| 12792 | 12824 |
| 12793 bool AllocationSite::IsNestedSite() { | 12825 bool AllocationSite::IsNestedSite() { |
| 12794 ASSERT(FLAG_trace_track_allocation_sites); | 12826 ASSERT(FLAG_trace_track_allocation_sites); |
| 12795 Object* current = GetHeap()->allocation_sites_list(); | 12827 Object* current = GetHeap()->allocation_sites_list(); |
| 12796 while (current != NULL && current->IsAllocationSite()) { | 12828 while (current != NULL && current->IsAllocationSite()) { |
| 12797 AllocationSite* current_site = AllocationSite::cast(current); | 12829 AllocationSite* current_site = AllocationSite::cast(current); |
| 12798 if (current_site->nested_site() == this) { | 12830 if (current_site->nested_site() == this) { |
| 12799 return true; | 12831 return true; |
| 12800 } | 12832 } |
| 12801 current = current_site->weak_next(); | 12833 current = current_site->weak_next(); |
| 12802 } | 12834 } |
| 12803 return false; | 12835 return false; |
| 12804 } | 12836 } |
| 12805 | 12837 |
| 12806 | 12838 |
| 12807 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) { | 12839 MaybeObject* AllocationSite::DigestTransitionFeedback(ElementsKind to_kind) { |
| 12808 if (!FLAG_track_allocation_sites || !IsJSArray()) { | 12840 Isolate* isolate = GetIsolate(); |
| 12809 return this; | |
| 12810 } | |
| 12811 | 12841 |
| 12812 AllocationMemento* memento = AllocationMemento::FindForJSObject(this); | 12842 if (SitePointsToLiteral() && transition_info()->IsJSArray()) { |
| 12813 if (memento == NULL || !memento->IsValid()) { | 12843 JSArray* transition_info = JSArray::cast(this->transition_info()); |
| 12814 return this; | |
| 12815 } | |
| 12816 | |
| 12817 // Walk through to the Allocation Site | |
| 12818 AllocationSite* site = memento->GetAllocationSite(); | |
| 12819 if (site->SitePointsToLiteral() && | |
| 12820 site->transition_info()->IsJSArray()) { | |
| 12821 JSArray* transition_info = JSArray::cast(site->transition_info()); | |
| 12822 ElementsKind kind = transition_info->GetElementsKind(); | 12844 ElementsKind kind = transition_info->GetElementsKind(); |
| 12823 // if kind is holey ensure that to_kind is as well. | 12845 // if kind is holey ensure that to_kind is as well. |
| 12824 if (IsHoleyElementsKind(kind)) { | 12846 if (IsHoleyElementsKind(kind)) { |
| 12825 to_kind = GetHoleyElementsKind(to_kind); | 12847 to_kind = GetHoleyElementsKind(to_kind); |
| 12826 } | 12848 } |
| 12827 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { | 12849 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { |
| 12828 // If the array is huge, it's not likely to be defined in a local | 12850 // If the array is huge, it's not likely to be defined in a local |
| 12829 // function, so we shouldn't make new instances of it very often. | 12851 // function, so we shouldn't make new instances of it very often. |
| 12830 uint32_t length = 0; | 12852 uint32_t length = 0; |
| 12831 CHECK(transition_info->length()->ToArrayIndex(&length)); | 12853 CHECK(transition_info->length()->ToArrayIndex(&length)); |
| 12832 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) { | 12854 if (length <= kMaximumArrayBytesToPretransition) { |
| 12833 if (FLAG_trace_track_allocation_sites) { | 12855 if (FLAG_trace_track_allocation_sites) { |
| 12834 bool is_nested = site->IsNestedSite(); | 12856 bool is_nested = IsNestedSite(); |
| 12835 PrintF( | 12857 PrintF( |
| 12836 "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n", | 12858 "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n", |
| 12837 reinterpret_cast<void*>(this), | 12859 reinterpret_cast<void*>(this), |
| 12838 is_nested ? "(nested)" : "", | 12860 is_nested ? "(nested)" : "", |
| 12839 ElementsKindToString(kind), | 12861 ElementsKindToString(kind), |
| 12840 ElementsKindToString(to_kind)); | 12862 ElementsKindToString(to_kind)); |
| 12841 } | 12863 } |
| 12842 return transition_info->TransitionElementsKind(to_kind); | 12864 MaybeObject* result = transition_info->TransitionElementsKind(to_kind); |
| 12865 if (result->IsFailure()) return result; |
| 12866 dependent_code()->DeoptimizeDependentCodeGroup( |
| 12867 isolate, DependentCode::kAllocationSiteTransitionChangedGroup); |
| 12843 } | 12868 } |
| 12844 } | 12869 } |
| 12845 } else { | 12870 } else { |
| 12846 ElementsKind kind = site->GetElementsKind(); | 12871 ElementsKind kind = GetElementsKind(); |
| 12847 // if kind is holey ensure that to_kind is as well. | 12872 // if kind is holey ensure that to_kind is as well. |
| 12848 if (IsHoleyElementsKind(kind)) { | 12873 if (IsHoleyElementsKind(kind)) { |
| 12849 to_kind = GetHoleyElementsKind(to_kind); | 12874 to_kind = GetHoleyElementsKind(to_kind); |
| 12850 } | 12875 } |
| 12851 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { | 12876 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { |
| 12852 if (FLAG_trace_track_allocation_sites) { | 12877 if (FLAG_trace_track_allocation_sites) { |
| 12853 PrintF("AllocationSite: JSArray %p site updated %s->%s\n", | 12878 PrintF("AllocationSite: JSArray %p site updated %s->%s\n", |
| 12854 reinterpret_cast<void*>(this), | 12879 reinterpret_cast<void*>(this), |
| 12855 ElementsKindToString(kind), | 12880 ElementsKindToString(kind), |
| 12856 ElementsKindToString(to_kind)); | 12881 ElementsKindToString(to_kind)); |
| 12857 } | 12882 } |
| 12858 site->set_transition_info(Smi::FromInt(to_kind)); | 12883 SetElementsKind(to_kind); |
| 12884 dependent_code()->DeoptimizeDependentCodeGroup( |
| 12885 isolate, DependentCode::kAllocationSiteTransitionChangedGroup); |
| 12859 } | 12886 } |
| 12860 } | 12887 } |
| 12861 return this; | 12888 return this; |
| 12862 } | 12889 } |
| 12863 | 12890 |
| 12864 | 12891 |
| 12892 void AllocationSite::AddDependentCompilationInfo(Reason reason, |
| 12893 CompilationInfo* info) { |
| 12894 DependentCode::DependencyGroup group = ToDependencyGroup(reason); |
| 12895 Handle<DependentCode> dep(dependent_code()); |
| 12896 Handle<DependentCode> codes = |
| 12897 DependentCode::Insert(dep, group, info->object_wrapper()); |
| 12898 if (*codes != dependent_code()) set_dependent_code(*codes); |
| 12899 info->dependencies(group)->Add(Handle<HeapObject>(this), info->zone()); |
| 12900 } |
| 12901 |
| 12902 |
| 12903 void AllocationSite::AddDependentCode(Reason reason, Handle<Code> code) { |
| 12904 DependentCode::DependencyGroup group = ToDependencyGroup(reason); |
| 12905 Handle<DependentCode> codes = DependentCode::Insert( |
| 12906 Handle<DependentCode>(dependent_code()), group, code); |
| 12907 if (*codes != dependent_code()) set_dependent_code(*codes); |
| 12908 } |
| 12909 |
| 12910 |
| 12911 void JSObject::UpdateAllocationSite(Handle<JSObject> object, |
| 12912 ElementsKind to_kind) { |
| 12913 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), |
| 12914 object->UpdateAllocationSite(to_kind)); |
| 12915 } |
| 12916 |
| 12917 |
| 12918 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) { |
| 12919 if (!FLAG_track_allocation_sites || !IsJSArray()) { |
| 12920 return this; |
| 12921 } |
| 12922 |
| 12923 AllocationMemento* memento = AllocationMemento::FindForJSObject(this); |
| 12924 if (memento == NULL || !memento->IsValid()) { |
| 12925 return this; |
| 12926 } |
| 12927 |
| 12928 // Walk through to the Allocation Site |
| 12929 AllocationSite* site = memento->GetAllocationSite(); |
| 12930 return site->DigestTransitionFeedback(to_kind); |
| 12931 } |
| 12932 |
| 12933 |
| 12865 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { | 12934 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { |
| 12866 ASSERT(!map()->is_observed()); | |
| 12867 ElementsKind from_kind = map()->elements_kind(); | 12935 ElementsKind from_kind = map()->elements_kind(); |
| 12868 | 12936 |
| 12869 if (IsFastHoleyElementsKind(from_kind)) { | 12937 if (IsFastHoleyElementsKind(from_kind)) { |
| 12870 to_kind = GetHoleyElementsKind(to_kind); | 12938 to_kind = GetHoleyElementsKind(to_kind); |
| 12871 } | 12939 } |
| 12872 | 12940 |
| 12873 if (from_kind == to_kind) return this; | 12941 if (from_kind == to_kind) return this; |
| 12874 // Don't update the site if to_kind isn't fast | 12942 // Don't update the site if to_kind isn't fast |
| 12875 if (IsFastElementsKind(to_kind)) { | 12943 if (IsFastElementsKind(to_kind)) { |
| 12876 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); | 12944 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12944 if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) { | 13012 if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) { |
| 12945 return false; | 13013 return false; |
| 12946 } | 13014 } |
| 12947 | 13015 |
| 12948 // Transitions from HOLEY -> PACKED are not allowed. | 13016 // Transitions from HOLEY -> PACKED are not allowed. |
| 12949 return !IsFastHoleyElementsKind(from_kind) || | 13017 return !IsFastHoleyElementsKind(from_kind) || |
| 12950 IsFastHoleyElementsKind(to_kind); | 13018 IsFastHoleyElementsKind(to_kind); |
| 12951 } | 13019 } |
| 12952 | 13020 |
| 12953 | 13021 |
| 13022 void JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray> array, |
| 13023 uint32_t index, |
| 13024 Handle<Object> value) { |
| 13025 CALL_HEAP_FUNCTION_VOID(array->GetIsolate(), |
| 13026 array->JSArrayUpdateLengthFromIndex(index, *value)); |
| 13027 } |
| 13028 |
| 13029 |
| 12954 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, | 13030 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, |
| 12955 Object* value) { | 13031 Object* value) { |
| 12956 uint32_t old_len = 0; | 13032 uint32_t old_len = 0; |
| 12957 CHECK(length()->ToArrayIndex(&old_len)); | 13033 CHECK(length()->ToArrayIndex(&old_len)); |
| 12958 // Check to see if we need to update the length. For now, we make | 13034 // Check to see if we need to update the length. For now, we make |
| 12959 // sure that the length stays within 32-bits (unsigned). | 13035 // sure that the length stays within 32-bits (unsigned). |
| 12960 if (index >= old_len && index != 0xffffffff) { | 13036 if (index >= old_len && index != 0xffffffff) { |
| 12961 Object* len; | 13037 Object* len; |
| 12962 { MaybeObject* maybe_len = | 13038 { MaybeObject* maybe_len = |
| 12963 GetHeap()->NumberFromDouble(static_cast<double>(index) + 1); | 13039 GetHeap()->NumberFromDouble(static_cast<double>(index) + 1); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13049 // Fall through if packing is not guaranteed. | 13125 // Fall through if packing is not guaranteed. |
| 13050 case FAST_HOLEY_SMI_ELEMENTS: | 13126 case FAST_HOLEY_SMI_ELEMENTS: |
| 13051 case FAST_HOLEY_ELEMENTS: | 13127 case FAST_HOLEY_ELEMENTS: |
| 13052 backing_store = FixedArray::cast(backing_store_base); | 13128 backing_store = FixedArray::cast(backing_store_base); |
| 13053 *capacity = backing_store->length(); | 13129 *capacity = backing_store->length(); |
| 13054 for (int i = 0; i < *capacity; ++i) { | 13130 for (int i = 0; i < *capacity; ++i) { |
| 13055 if (!backing_store->get(i)->IsTheHole()) ++(*used); | 13131 if (!backing_store->get(i)->IsTheHole()) ++(*used); |
| 13056 } | 13132 } |
| 13057 break; | 13133 break; |
| 13058 case DICTIONARY_ELEMENTS: { | 13134 case DICTIONARY_ELEMENTS: { |
| 13059 SeededNumberDictionary* dictionary = | 13135 SeededNumberDictionary* dictionary = element_dictionary(); |
| 13060 SeededNumberDictionary::cast(FixedArray::cast(elements())); | |
| 13061 *capacity = dictionary->Capacity(); | 13136 *capacity = dictionary->Capacity(); |
| 13062 *used = dictionary->NumberOfElements(); | 13137 *used = dictionary->NumberOfElements(); |
| 13063 break; | 13138 break; |
| 13064 } | 13139 } |
| 13065 case FAST_DOUBLE_ELEMENTS: | 13140 case FAST_DOUBLE_ELEMENTS: |
| 13066 if (IsJSArray()) { | 13141 if (IsJSArray()) { |
| 13067 *capacity = backing_store_base->length(); | 13142 *capacity = backing_store_base->length(); |
| 13068 *used = Smi::cast(JSArray::cast(this)->length())->value(); | 13143 *used = Smi::cast(JSArray::cast(this)->length())->value(); |
| 13069 break; | 13144 break; |
| 13070 } | 13145 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13149 SeededNumberDictionary::kEntrySize; | 13224 SeededNumberDictionary::kEntrySize; |
| 13150 return 2 * dictionary_size >= array_size; | 13225 return 2 * dictionary_size >= array_size; |
| 13151 } | 13226 } |
| 13152 | 13227 |
| 13153 | 13228 |
| 13154 bool JSObject::ShouldConvertToFastDoubleElements( | 13229 bool JSObject::ShouldConvertToFastDoubleElements( |
| 13155 bool* has_smi_only_elements) { | 13230 bool* has_smi_only_elements) { |
| 13156 *has_smi_only_elements = false; | 13231 *has_smi_only_elements = false; |
| 13157 if (FLAG_unbox_double_arrays) { | 13232 if (FLAG_unbox_double_arrays) { |
| 13158 ASSERT(HasDictionaryElements()); | 13233 ASSERT(HasDictionaryElements()); |
| 13159 SeededNumberDictionary* dictionary = | 13234 SeededNumberDictionary* dictionary = element_dictionary(); |
| 13160 SeededNumberDictionary::cast(elements()); | |
| 13161 bool found_double = false; | 13235 bool found_double = false; |
| 13162 for (int i = 0; i < dictionary->Capacity(); i++) { | 13236 for (int i = 0; i < dictionary->Capacity(); i++) { |
| 13163 Object* key = dictionary->KeyAt(i); | 13237 Object* key = dictionary->KeyAt(i); |
| 13164 if (key->IsNumber()) { | 13238 if (key->IsNumber()) { |
| 13165 Object* value = dictionary->ValueAt(i); | 13239 Object* value = dictionary->ValueAt(i); |
| 13166 if (!value->IsNumber()) return false; | 13240 if (!value->IsNumber()) return false; |
| 13167 if (!value->IsSmi()) { | 13241 if (!value->IsSmi()) { |
| 13168 found_double = true; | 13242 found_double = true; |
| 13169 } | 13243 } |
| 13170 } | 13244 } |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13372 return result.IsPropertyCallbacks(); | 13446 return result.IsPropertyCallbacks(); |
| 13373 } | 13447 } |
| 13374 | 13448 |
| 13375 | 13449 |
| 13376 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { | 13450 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { |
| 13377 if (HasFastProperties()) { | 13451 if (HasFastProperties()) { |
| 13378 Map* map = this->map(); | 13452 Map* map = this->map(); |
| 13379 if (filter == NONE) return map->NumberOfOwnDescriptors(); | 13453 if (filter == NONE) return map->NumberOfOwnDescriptors(); |
| 13380 if (filter & DONT_ENUM) { | 13454 if (filter & DONT_ENUM) { |
| 13381 int result = map->EnumLength(); | 13455 int result = map->EnumLength(); |
| 13382 if (result != Map::kInvalidEnumCache) return result; | 13456 if (result != kInvalidEnumCacheSentinel) return result; |
| 13383 } | 13457 } |
| 13384 return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter); | 13458 return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter); |
| 13385 } | 13459 } |
| 13386 return property_dictionary()->NumberOfElementsFilterAttributes(filter); | 13460 return property_dictionary()->NumberOfElementsFilterAttributes(filter); |
| 13387 } | 13461 } |
| 13388 | 13462 |
| 13389 | 13463 |
| 13390 void FixedArray::SwapPairs(FixedArray* numbers, int i, int j) { | 13464 void FixedArray::SwapPairs(FixedArray* numbers, int i, int j) { |
| 13391 Object* temp = get(i); | 13465 Object* temp = get(i); |
| 13392 set(i, get(j)); | 13466 set(i, get(j)); |
| (...skipping 1135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14528 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); | 14602 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure); |
| 14529 dict->CopyValuesTo(*fast_elements); | 14603 dict->CopyValuesTo(*fast_elements); |
| 14530 object->ValidateElements(); | 14604 object->ValidateElements(); |
| 14531 | 14605 |
| 14532 object->set_map_and_elements(*new_map, *fast_elements); | 14606 object->set_map_and_elements(*new_map, *fast_elements); |
| 14533 } else if (object->HasExternalArrayElements()) { | 14607 } else if (object->HasExternalArrayElements()) { |
| 14534 // External arrays cannot have holes or undefined elements. | 14608 // External arrays cannot have holes or undefined elements. |
| 14535 return handle(Smi::FromInt( | 14609 return handle(Smi::FromInt( |
| 14536 ExternalArray::cast(object->elements())->length()), isolate); | 14610 ExternalArray::cast(object->elements())->length()), isolate); |
| 14537 } else if (!object->HasFastDoubleElements()) { | 14611 } else if (!object->HasFastDoubleElements()) { |
| 14538 JSObject::EnsureWritableFastElements(object); | 14612 EnsureWritableFastElements(object); |
| 14539 } | 14613 } |
| 14540 ASSERT(object->HasFastSmiOrObjectElements() || | 14614 ASSERT(object->HasFastSmiOrObjectElements() || |
| 14541 object->HasFastDoubleElements()); | 14615 object->HasFastDoubleElements()); |
| 14542 | 14616 |
| 14543 // Collect holes at the end, undefined before that and the rest at the | 14617 // Collect holes at the end, undefined before that and the rest at the |
| 14544 // start, and return the number of non-hole, non-undefined values. | 14618 // start, and return the number of non-hole, non-undefined values. |
| 14545 | 14619 |
| 14546 Handle<FixedArrayBase> elements_base(object->elements()); | 14620 Handle<FixedArrayBase> elements_base(object->elements()); |
| 14547 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); | 14621 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); |
| 14548 if (limit > elements_length) { | 14622 if (limit > elements_length) { |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14735 // Clamp undefined to zero (default). All other types have been | 14809 // Clamp undefined to zero (default). All other types have been |
| 14736 // converted to a number type further up in the call chain. | 14810 // converted to a number type further up in the call chain. |
| 14737 ASSERT(value->IsUndefined()); | 14811 ASSERT(value->IsUndefined()); |
| 14738 } | 14812 } |
| 14739 receiver->set(index, cast_value); | 14813 receiver->set(index, cast_value); |
| 14740 } | 14814 } |
| 14741 return heap->NumberFromInt32(cast_value); | 14815 return heap->NumberFromInt32(cast_value); |
| 14742 } | 14816 } |
| 14743 | 14817 |
| 14744 | 14818 |
| 14819 Handle<Object> ExternalByteArray::SetValue(Handle<ExternalByteArray> array, |
| 14820 uint32_t index, |
| 14821 Handle<Object> value) { |
| 14822 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14823 array->SetValue(index, *value), |
| 14824 Object); |
| 14825 } |
| 14826 |
| 14827 |
| 14745 MaybeObject* ExternalByteArray::SetValue(uint32_t index, Object* value) { | 14828 MaybeObject* ExternalByteArray::SetValue(uint32_t index, Object* value) { |
| 14746 return ExternalArrayIntSetter<ExternalByteArray, int8_t> | 14829 return ExternalArrayIntSetter<ExternalByteArray, int8_t> |
| 14747 (GetHeap(), this, index, value); | 14830 (GetHeap(), this, index, value); |
| 14748 } | 14831 } |
| 14749 | 14832 |
| 14750 | 14833 |
| 14834 Handle<Object> ExternalUnsignedByteArray::SetValue( |
| 14835 Handle<ExternalUnsignedByteArray> array, |
| 14836 uint32_t index, |
| 14837 Handle<Object> value) { |
| 14838 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14839 array->SetValue(index, *value), |
| 14840 Object); |
| 14841 } |
| 14842 |
| 14843 |
| 14751 MaybeObject* ExternalUnsignedByteArray::SetValue(uint32_t index, | 14844 MaybeObject* ExternalUnsignedByteArray::SetValue(uint32_t index, |
| 14752 Object* value) { | 14845 Object* value) { |
| 14753 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t> | 14846 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t> |
| 14754 (GetHeap(), this, index, value); | 14847 (GetHeap(), this, index, value); |
| 14755 } | 14848 } |
| 14756 | 14849 |
| 14757 | 14850 |
| 14851 Handle<Object> ExternalShortArray::SetValue( |
| 14852 Handle<ExternalShortArray> array, |
| 14853 uint32_t index, |
| 14854 Handle<Object> value) { |
| 14855 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14856 array->SetValue(index, *value), |
| 14857 Object); |
| 14858 } |
| 14859 |
| 14860 |
| 14758 MaybeObject* ExternalShortArray::SetValue(uint32_t index, | 14861 MaybeObject* ExternalShortArray::SetValue(uint32_t index, |
| 14759 Object* value) { | 14862 Object* value) { |
| 14760 return ExternalArrayIntSetter<ExternalShortArray, int16_t> | 14863 return ExternalArrayIntSetter<ExternalShortArray, int16_t> |
| 14761 (GetHeap(), this, index, value); | 14864 (GetHeap(), this, index, value); |
| 14762 } | 14865 } |
| 14763 | 14866 |
| 14764 | 14867 |
| 14868 Handle<Object> ExternalUnsignedShortArray::SetValue( |
| 14869 Handle<ExternalUnsignedShortArray> array, |
| 14870 uint32_t index, |
| 14871 Handle<Object> value) { |
| 14872 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14873 array->SetValue(index, *value), |
| 14874 Object); |
| 14875 } |
| 14876 |
| 14877 |
| 14765 MaybeObject* ExternalUnsignedShortArray::SetValue(uint32_t index, | 14878 MaybeObject* ExternalUnsignedShortArray::SetValue(uint32_t index, |
| 14766 Object* value) { | 14879 Object* value) { |
| 14767 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t> | 14880 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t> |
| 14768 (GetHeap(), this, index, value); | 14881 (GetHeap(), this, index, value); |
| 14769 } | 14882 } |
| 14770 | 14883 |
| 14771 | 14884 |
| 14885 Handle<Object> ExternalIntArray::SetValue(Handle<ExternalIntArray> array, |
| 14886 uint32_t index, |
| 14887 Handle<Object> value) { |
| 14888 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14889 array->SetValue(index, *value), |
| 14890 Object); |
| 14891 } |
| 14892 |
| 14893 |
| 14772 MaybeObject* ExternalIntArray::SetValue(uint32_t index, Object* value) { | 14894 MaybeObject* ExternalIntArray::SetValue(uint32_t index, Object* value) { |
| 14773 return ExternalArrayIntSetter<ExternalIntArray, int32_t> | 14895 return ExternalArrayIntSetter<ExternalIntArray, int32_t> |
| 14774 (GetHeap(), this, index, value); | 14896 (GetHeap(), this, index, value); |
| 14775 } | 14897 } |
| 14776 | 14898 |
| 14777 | 14899 |
| 14900 Handle<Object> ExternalUnsignedIntArray::SetValue( |
| 14901 Handle<ExternalUnsignedIntArray> array, |
| 14902 uint32_t index, |
| 14903 Handle<Object> value) { |
| 14904 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14905 array->SetValue(index, *value), |
| 14906 Object); |
| 14907 } |
| 14908 |
| 14909 |
| 14778 MaybeObject* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) { | 14910 MaybeObject* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) { |
| 14779 uint32_t cast_value = 0; | 14911 uint32_t cast_value = 0; |
| 14780 Heap* heap = GetHeap(); | 14912 Heap* heap = GetHeap(); |
| 14781 if (index < static_cast<uint32_t>(length())) { | 14913 if (index < static_cast<uint32_t>(length())) { |
| 14782 if (value->IsSmi()) { | 14914 if (value->IsSmi()) { |
| 14783 int int_value = Smi::cast(value)->value(); | 14915 int int_value = Smi::cast(value)->value(); |
| 14784 cast_value = static_cast<uint32_t>(int_value); | 14916 cast_value = static_cast<uint32_t>(int_value); |
| 14785 } else if (value->IsHeapNumber()) { | 14917 } else if (value->IsHeapNumber()) { |
| 14786 double double_value = HeapNumber::cast(value)->value(); | 14918 double double_value = HeapNumber::cast(value)->value(); |
| 14787 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); | 14919 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); |
| 14788 } else { | 14920 } else { |
| 14789 // Clamp undefined to zero (default). All other types have been | 14921 // Clamp undefined to zero (default). All other types have been |
| 14790 // converted to a number type further up in the call chain. | 14922 // converted to a number type further up in the call chain. |
| 14791 ASSERT(value->IsUndefined()); | 14923 ASSERT(value->IsUndefined()); |
| 14792 } | 14924 } |
| 14793 set(index, cast_value); | 14925 set(index, cast_value); |
| 14794 } | 14926 } |
| 14795 return heap->NumberFromUint32(cast_value); | 14927 return heap->NumberFromUint32(cast_value); |
| 14796 } | 14928 } |
| 14797 | 14929 |
| 14798 | 14930 |
| 14931 Handle<Object> ExternalFloatArray::SetValue(Handle<ExternalFloatArray> array, |
| 14932 uint32_t index, |
| 14933 Handle<Object> value) { |
| 14934 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14935 array->SetValue(index, *value), |
| 14936 Object); |
| 14937 } |
| 14938 |
| 14939 |
| 14799 MaybeObject* ExternalFloatArray::SetValue(uint32_t index, Object* value) { | 14940 MaybeObject* ExternalFloatArray::SetValue(uint32_t index, Object* value) { |
| 14800 float cast_value = static_cast<float>(OS::nan_value()); | 14941 float cast_value = static_cast<float>(OS::nan_value()); |
| 14801 Heap* heap = GetHeap(); | 14942 Heap* heap = GetHeap(); |
| 14802 if (index < static_cast<uint32_t>(length())) { | 14943 if (index < static_cast<uint32_t>(length())) { |
| 14803 if (value->IsSmi()) { | 14944 if (value->IsSmi()) { |
| 14804 int int_value = Smi::cast(value)->value(); | 14945 int int_value = Smi::cast(value)->value(); |
| 14805 cast_value = static_cast<float>(int_value); | 14946 cast_value = static_cast<float>(int_value); |
| 14806 } else if (value->IsHeapNumber()) { | 14947 } else if (value->IsHeapNumber()) { |
| 14807 double double_value = HeapNumber::cast(value)->value(); | 14948 double double_value = HeapNumber::cast(value)->value(); |
| 14808 cast_value = static_cast<float>(double_value); | 14949 cast_value = static_cast<float>(double_value); |
| 14809 } else { | 14950 } else { |
| 14810 // Clamp undefined to NaN (default). All other types have been | 14951 // Clamp undefined to NaN (default). All other types have been |
| 14811 // converted to a number type further up in the call chain. | 14952 // converted to a number type further up in the call chain. |
| 14812 ASSERT(value->IsUndefined()); | 14953 ASSERT(value->IsUndefined()); |
| 14813 } | 14954 } |
| 14814 set(index, cast_value); | 14955 set(index, cast_value); |
| 14815 } | 14956 } |
| 14816 return heap->AllocateHeapNumber(cast_value); | 14957 return heap->AllocateHeapNumber(cast_value); |
| 14817 } | 14958 } |
| 14818 | 14959 |
| 14819 | 14960 |
| 14961 Handle<Object> ExternalDoubleArray::SetValue(Handle<ExternalDoubleArray> array, |
| 14962 uint32_t index, |
| 14963 Handle<Object> value) { |
| 14964 CALL_HEAP_FUNCTION(array->GetIsolate(), |
| 14965 array->SetValue(index, *value), |
| 14966 Object); |
| 14967 } |
| 14968 |
| 14969 |
| 14820 MaybeObject* ExternalDoubleArray::SetValue(uint32_t index, Object* value) { | 14970 MaybeObject* ExternalDoubleArray::SetValue(uint32_t index, Object* value) { |
| 14821 double double_value = OS::nan_value(); | 14971 double double_value = OS::nan_value(); |
| 14822 Heap* heap = GetHeap(); | 14972 Heap* heap = GetHeap(); |
| 14823 if (index < static_cast<uint32_t>(length())) { | 14973 if (index < static_cast<uint32_t>(length())) { |
| 14824 if (value->IsSmi()) { | 14974 if (value->IsSmi()) { |
| 14825 int int_value = Smi::cast(value)->value(); | 14975 int int_value = Smi::cast(value)->value(); |
| 14826 double_value = static_cast<double>(int_value); | 14976 double_value = static_cast<double>(int_value); |
| 14827 } else if (value->IsHeapNumber()) { | 14977 } else if (value->IsHeapNumber()) { |
| 14828 double_value = HeapNumber::cast(value)->value(); | 14978 double_value = HeapNumber::cast(value)->value(); |
| 14829 } else { | 14979 } else { |
| (...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15431 return; | 15581 return; |
| 15432 } | 15582 } |
| 15433 // Update max key value. | 15583 // Update max key value. |
| 15434 Object* max_index_object = get(kMaxNumberKeyIndex); | 15584 Object* max_index_object = get(kMaxNumberKeyIndex); |
| 15435 if (!max_index_object->IsSmi() || max_number_key() < key) { | 15585 if (!max_index_object->IsSmi() || max_number_key() < key) { |
| 15436 FixedArray::set(kMaxNumberKeyIndex, | 15586 FixedArray::set(kMaxNumberKeyIndex, |
| 15437 Smi::FromInt(key << kRequiresSlowElementsTagSize)); | 15587 Smi::FromInt(key << kRequiresSlowElementsTagSize)); |
| 15438 } | 15588 } |
| 15439 } | 15589 } |
| 15440 | 15590 |
| 15591 Handle<SeededNumberDictionary> SeededNumberDictionary::AddNumberEntry( |
| 15592 Handle<SeededNumberDictionary> dictionary, |
| 15593 uint32_t key, |
| 15594 Handle<Object> value, |
| 15595 PropertyDetails details) { |
| 15596 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), |
| 15597 dictionary->AddNumberEntry(key, *value, details), |
| 15598 SeededNumberDictionary); |
| 15599 } |
| 15441 | 15600 |
| 15442 MaybeObject* SeededNumberDictionary::AddNumberEntry(uint32_t key, | 15601 MaybeObject* SeededNumberDictionary::AddNumberEntry(uint32_t key, |
| 15443 Object* value, | 15602 Object* value, |
| 15444 PropertyDetails details) { | 15603 PropertyDetails details) { |
| 15445 UpdateMaxNumberKey(key); | 15604 UpdateMaxNumberKey(key); |
| 15446 SLOW_ASSERT(this->FindEntry(key) == kNotFound); | 15605 SLOW_ASSERT(this->FindEntry(key) == kNotFound); |
| 15447 return Add(key, value, details); | 15606 return Add(key, value, details); |
| 15448 } | 15607 } |
| 15449 | 15608 |
| 15450 | 15609 |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15654 Heap* heap = Dictionary<Shape, Key>::GetHeap(); | 15813 Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
| 15655 return heap->undefined_value(); | 15814 return heap->undefined_value(); |
| 15656 } | 15815 } |
| 15657 | 15816 |
| 15658 | 15817 |
| 15659 MaybeObject* NameDictionary::TransformPropertiesToFastFor( | 15818 MaybeObject* NameDictionary::TransformPropertiesToFastFor( |
| 15660 JSObject* obj, int unused_property_fields) { | 15819 JSObject* obj, int unused_property_fields) { |
| 15661 // Make sure we preserve dictionary representation if there are too many | 15820 // Make sure we preserve dictionary representation if there are too many |
| 15662 // descriptors. | 15821 // descriptors. |
| 15663 int number_of_elements = NumberOfElements(); | 15822 int number_of_elements = NumberOfElements(); |
| 15664 if (number_of_elements > DescriptorArray::kMaxNumberOfDescriptors) return obj; | 15823 if (number_of_elements > kMaxNumberOfDescriptors) return obj; |
| 15665 | 15824 |
| 15666 if (number_of_elements != NextEnumerationIndex()) { | 15825 if (number_of_elements != NextEnumerationIndex()) { |
| 15667 MaybeObject* maybe_result = GenerateNewEnumerationIndices(); | 15826 MaybeObject* maybe_result = GenerateNewEnumerationIndices(); |
| 15668 if (maybe_result->IsFailure()) return maybe_result; | 15827 if (maybe_result->IsFailure()) return maybe_result; |
| 15669 } | 15828 } |
| 15670 | 15829 |
| 15671 int instance_descriptor_length = 0; | 15830 int instance_descriptor_length = 0; |
| 15672 int number_of_fields = 0; | 15831 int number_of_fields = 0; |
| 15673 | 15832 |
| 15674 Heap* heap = GetHeap(); | 15833 Heap* heap = GetHeap(); |
| (...skipping 851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16526 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16685 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16527 static const char* error_messages_[] = { | 16686 static const char* error_messages_[] = { |
| 16528 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16687 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16529 }; | 16688 }; |
| 16530 #undef ERROR_MESSAGES_TEXTS | 16689 #undef ERROR_MESSAGES_TEXTS |
| 16531 return error_messages_[reason]; | 16690 return error_messages_[reason]; |
| 16532 } | 16691 } |
| 16533 | 16692 |
| 16534 | 16693 |
| 16535 } } // namespace v8::internal | 16694 } } // namespace v8::internal |
| OLD | NEW |