Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: src/objects.cc

Issue 7172030: Revert "Merge arguments branch to bleeding merge." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 1879 matching lines...) Expand 10 before | Expand all | Expand 10 after
1890 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( 1890 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(
1891 uint32_t index, 1891 uint32_t index,
1892 Object* value, 1892 Object* value,
1893 bool* found, 1893 bool* found,
1894 StrictModeFlag strict_mode) { 1894 StrictModeFlag strict_mode) {
1895 Heap* heap = GetHeap(); 1895 Heap* heap = GetHeap();
1896 for (Object* pt = GetPrototype(); 1896 for (Object* pt = GetPrototype();
1897 pt != heap->null_value(); 1897 pt != heap->null_value();
1898 pt = pt->GetPrototype()) { 1898 pt = pt->GetPrototype()) {
1899 if (!JSObject::cast(pt)->HasDictionaryElements()) { 1899 if (!JSObject::cast(pt)->HasDictionaryElements()) {
1900 continue; 1900 continue;
1901 } 1901 }
1902 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary(); 1902 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary();
1903 int entry = dictionary->FindEntry(index); 1903 int entry = dictionary->FindEntry(index);
1904 if (entry != NumberDictionary::kNotFound) { 1904 if (entry != NumberDictionary::kNotFound) {
1905 PropertyDetails details = dictionary->DetailsAt(entry); 1905 PropertyDetails details = dictionary->DetailsAt(entry);
1906 if (details.type() == CALLBACKS) { 1906 if (details.type() == CALLBACKS) {
1907 *found = true; 1907 *found = true;
1908 return SetElementWithCallback(dictionary->ValueAt(entry), 1908 return SetElementWithCallback(dictionary->ValueAt(entry),
1909 index, 1909 index,
1910 value, 1910 value,
(...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after
2797 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) { 2797 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) {
2798 if (HasFastProperties()) return this; 2798 if (HasFastProperties()) return this;
2799 ASSERT(!IsGlobalObject()); 2799 ASSERT(!IsGlobalObject());
2800 return property_dictionary()-> 2800 return property_dictionary()->
2801 TransformPropertiesToFastFor(this, unused_property_fields); 2801 TransformPropertiesToFastFor(this, unused_property_fields);
2802 } 2802 }
2803 2803
2804 2804
2805 MaybeObject* JSObject::NormalizeElements() { 2805 MaybeObject* JSObject::NormalizeElements() {
2806 ASSERT(!HasExternalArrayElements()); 2806 ASSERT(!HasExternalArrayElements());
2807 if (HasDictionaryElements()) return this;
2808 Map* old_map = map();
2809 ASSERT(old_map->has_fast_elements() || old_map->has_fast_double_elements());
2807 2810
2808 // Find the backing store. 2811 Object* obj;
2809 FixedArray* array = FixedArray::cast(elements()); 2812 { MaybeObject* maybe_obj = old_map->GetSlowElementsMap();
2810 Map* old_map = array->map(); 2813 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2811 bool is_arguments =
2812 (old_map == old_map->heap()->non_strict_arguments_elements_map());
2813 if (is_arguments) {
2814 array = FixedArray::cast(array->get(1));
2815 } 2814 }
2816 if (array->IsDictionary()) return array; 2815 Map* new_map = Map::cast(obj);
2817 2816
2818 ASSERT(HasFastElements() || HasFastArgumentsElements()); 2817 // Get number of entries.
2819 // Compute the effective length and allocate a new backing store. 2818 FixedArrayBase* array = FixedArrayBase::cast(elements());
2820 int length = IsJSArray() 2819
2821 ? Smi::cast(JSArray::cast(this)->length())->value() 2820 // Compute the effective length.
2822 : array->length(); 2821 int length = IsJSArray() ?
2823 NumberDictionary* dictionary = NULL; 2822 Smi::cast(JSArray::cast(this)->length())->value() :
2824 { Object* object; 2823 array->length();
2825 MaybeObject* maybe = NumberDictionary::Allocate(length); 2824 { MaybeObject* maybe_obj = NumberDictionary::Allocate(length);
2826 if (!maybe->ToObject(&object)) return maybe; 2825 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2827 dictionary = NumberDictionary::cast(object);
2828 } 2826 }
2829
2830 // Copy the elements to the new backing store.
2831 bool has_double_elements = old_map->has_fast_double_elements(); 2827 bool has_double_elements = old_map->has_fast_double_elements();
2828 NumberDictionary* dictionary = NumberDictionary::cast(obj);
2829 // Copy entries.
2832 for (int i = 0; i < length; i++) { 2830 for (int i = 0; i < length; i++) {
2833 Object* value = NULL; 2831 Object* value = NULL;
2834 if (has_double_elements) { 2832 if (has_double_elements) {
2835 FixedDoubleArray* double_array = FixedDoubleArray::cast(array); 2833 FixedDoubleArray* double_array = FixedDoubleArray::cast(array);
2836 if (double_array->is_the_hole(i)) { 2834 if (double_array->is_the_hole(i)) {
2837 value = GetIsolate()->heap()->the_hole_value(); 2835 value = GetIsolate()->heap()->the_hole_value();
2838 } else { 2836 } else {
2839 // Objects must be allocated in the old object space, since the 2837 // Objects must be allocated in the old object space, since the
2840 // overall number of HeapNumbers needed for the conversion might 2838 // overall number of HeapNumbers needed for the conversion might
2841 // exceed the capacity of new space, and we would fail repeatedly 2839 // exceed the capacity of new space, and we would fail repeatedly
2842 // trying to convert the FixedDoubleArray. 2840 // trying to convert the FixedDoubleArray.
2843 MaybeObject* maybe_value_object = 2841 MaybeObject* maybe_value_object =
2844 GetHeap()->AllocateHeapNumber(double_array->get(i), TENURED); 2842 GetHeap()->AllocateHeapNumber(double_array->get(i), TENURED);
2845 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; 2843 if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
2846 } 2844 }
2847 } else { 2845 } else {
2848 ASSERT(old_map->has_fast_elements()); 2846 ASSERT(old_map->has_fast_elements());
2849 value = array->get(i); 2847 FixedArray* fixed_array = FixedArray::cast(array);
2848 value = fixed_array->get(i);
2850 } 2849 }
2851 PropertyDetails details = PropertyDetails(NONE, NORMAL); 2850 PropertyDetails details = PropertyDetails(NONE, NORMAL);
2852 if (!value->IsTheHole()) { 2851 if (!value->IsTheHole()) {
2853 Object* result; 2852 Object* result;
2854 MaybeObject* maybe_result = 2853 MaybeObject* maybe_result =
2855 dictionary->AddNumberEntry(i, value, details); 2854 dictionary->AddNumberEntry(i, value, details);
2856 if (!maybe_result->ToObject(&result)) return maybe_result; 2855 if (!maybe_result->ToObject(&result)) return maybe_result;
2857 dictionary = NumberDictionary::cast(result); 2856 dictionary = NumberDictionary::cast(result);
2858 } 2857 }
2859 } 2858 }
2859 // Switch to using the dictionary as the backing storage for
2860 // elements. Set the new map first to satify the elements type
2861 // assert in set_elements().
2862 set_map(new_map);
2863 set_elements(dictionary);
2860 2864
2861 // Switch to using the dictionary as the backing storage for elements. 2865 new_map->heap()->isolate()->counters()->elements_to_dictionary()->
2862 if (is_arguments) { 2866 Increment();
2863 FixedArray::cast(elements())->set(1, dictionary);
2864 } else {
2865 // Set the new map first to satify the elements type assert in
2866 // set_elements().
2867 Object* new_map;
2868 MaybeObject* maybe = map()->GetSlowElementsMap();
2869 if (!maybe->ToObject(&new_map)) return maybe;
2870 set_map(Map::cast(new_map));
2871 set_elements(dictionary);
2872 }
2873
2874 old_map->isolate()->counters()->elements_to_dictionary()->Increment();
2875 2867
2876 #ifdef DEBUG 2868 #ifdef DEBUG
2877 if (FLAG_trace_normalization) { 2869 if (FLAG_trace_normalization) {
2878 PrintF("Object elements have been normalized:\n"); 2870 PrintF("Object elements have been normalized:\n");
2879 Print(); 2871 Print();
2880 } 2872 }
2881 #endif 2873 #endif
2882 2874
2883 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 2875 return this;
2884 return dictionary;
2885 } 2876 }
2886 2877
2887 2878
2888 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, 2879 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name,
2889 DeleteMode mode) { 2880 DeleteMode mode) {
2890 // Check local property, ignore interceptor. 2881 // Check local property, ignore interceptor.
2891 LookupResult result; 2882 LookupResult result;
2892 LocalLookupRealNamedProperty(name, &result); 2883 LocalLookupRealNamedProperty(name, &result);
2893 if (!result.IsProperty()) return GetHeap()->true_value(); 2884 if (!result.IsProperty()) return GetHeap()->true_value();
2894 2885
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2994 ASSERT(result->IsBoolean()); 2985 ASSERT(result->IsBoolean());
2995 return *v8::Utils::OpenHandle(*result); 2986 return *v8::Utils::OpenHandle(*result);
2996 } 2987 }
2997 MaybeObject* raw_result = 2988 MaybeObject* raw_result =
2998 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION); 2989 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION);
2999 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 2990 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
3000 return raw_result; 2991 return raw_result;
3001 } 2992 }
3002 2993
3003 2994
3004 MaybeObject* JSObject::DeleteFastElement(uint32_t index) {
3005 ASSERT(HasFastElements() || HasFastArgumentsElements());
3006 Heap* heap = GetHeap();
3007 FixedArray* backing_store = FixedArray::cast(elements());
3008 if (backing_store->map() == heap->non_strict_arguments_elements_map()) {
3009 backing_store = FixedArray::cast(backing_store->get(1));
3010 } else {
3011 Object* writable;
3012 MaybeObject* maybe = EnsureWritableFastElements();
3013 if (!maybe->ToObject(&writable)) return maybe;
3014 backing_store = FixedArray::cast(writable);
3015 }
3016 int length = IsJSArray()
3017 ? Smi::cast(JSArray::cast(this)->length())->value()
3018 : backing_store->length();
3019 if (index < static_cast<uint32_t>(length)) {
3020 backing_store->set_the_hole(index);
3021 }
3022 return heap->true_value();
3023 }
3024
3025
3026 MaybeObject* JSObject::DeleteDictionaryElement(uint32_t index,
3027 DeleteMode mode) {
3028 Isolate* isolate = GetIsolate();
3029 Heap* heap = isolate->heap();
3030 FixedArray* backing_store = FixedArray::cast(elements());
3031 if (backing_store->map() == heap->non_strict_arguments_elements_map()) {
3032 backing_store = FixedArray::cast(backing_store->get(1));
3033 }
3034 NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
3035 int entry = dictionary->FindEntry(index);
3036 if (entry != NumberDictionary::kNotFound) {
3037 Object* result = dictionary->DeleteProperty(entry, mode);
3038 if (mode == STRICT_DELETION && result == heap->false_value()) {
3039 // In strict mode, attempting to delete a non-configurable property
3040 // throws an exception.
3041 HandleScope scope(isolate);
3042 Handle<Object> name = isolate->factory()->NewNumberFromUint(index);
3043 Handle<Object> args[2] = { name, Handle<Object>(this) };
3044 Handle<Object> error =
3045 isolate->factory()->NewTypeError("strict_delete_property",
3046 HandleVector(args, 2));
3047 return isolate->Throw(*error);
3048 }
3049 }
3050 return heap->true_value();
3051 }
3052
3053
3054 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { 2995 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) {
3055 Isolate* isolate = GetIsolate(); 2996 Isolate* isolate = GetIsolate();
3056 // Check access rights if needed. 2997 // Check access rights if needed.
3057 if (IsAccessCheckNeeded() && 2998 if (IsAccessCheckNeeded() &&
3058 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { 2999 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) {
3059 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); 3000 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE);
3060 return isolate->heap()->false_value(); 3001 return isolate->heap()->false_value();
3061 } 3002 }
3062 3003
3063 if (IsJSGlobalProxy()) { 3004 if (IsJSGlobalProxy()) {
3064 Object* proto = GetPrototype(); 3005 Object* proto = GetPrototype();
3065 if (proto->IsNull()) return isolate->heap()->false_value(); 3006 if (proto->IsNull()) return isolate->heap()->false_value();
3066 ASSERT(proto->IsJSGlobalObject()); 3007 ASSERT(proto->IsJSGlobalObject());
3067 return JSGlobalObject::cast(proto)->DeleteElement(index, mode); 3008 return JSGlobalObject::cast(proto)->DeleteElement(index, mode);
3068 } 3009 }
3069 3010
3070 if (HasIndexedInterceptor()) { 3011 if (HasIndexedInterceptor()) {
3071 // Skip interceptor if forcing deletion. 3012 // Skip interceptor if forcing deletion.
3072 return (mode == FORCE_DELETION) 3013 if (mode == FORCE_DELETION) {
3073 ? DeleteElementPostInterceptor(index, FORCE_DELETION) 3014 return DeleteElementPostInterceptor(index, mode);
3074 : DeleteElementWithInterceptor(index); 3015 }
3016 return DeleteElementWithInterceptor(index);
3075 } 3017 }
3076 3018
3077 switch (GetElementsKind()) { 3019 switch (GetElementsKind()) {
3078 case FAST_ELEMENTS: 3020 case FAST_ELEMENTS: {
3079 return DeleteFastElement(index); 3021 Object* obj;
3080 3022 { MaybeObject* maybe_obj = EnsureWritableFastElements();
3081 case DICTIONARY_ELEMENTS: 3023 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3082 return DeleteDictionaryElement(index, mode); 3024 }
3083 3025 int length = IsJSArray()
3026 ? Smi::cast(JSArray::cast(this)->length())->value()
3027 : FixedArray::cast(elements())->length();
3028 if (index < static_cast<uint32_t>(length)) {
3029 FixedArray::cast(elements())->set_the_hole(index);
3030 }
3031 break;
3032 }
3084 case FAST_DOUBLE_ELEMENTS: { 3033 case FAST_DOUBLE_ELEMENTS: {
3085 int length = IsJSArray() 3034 int length = IsJSArray()
3086 ? Smi::cast(JSArray::cast(this)->length())->value() 3035 ? Smi::cast(JSArray::cast(this)->length())->value()
3087 : FixedArray::cast(elements())->length(); 3036 : FixedArray::cast(elements())->length();
3088 if (index < static_cast<uint32_t>(length)) { 3037 if (index < static_cast<uint32_t>(length)) {
3089 FixedDoubleArray::cast(elements())->set_the_hole(index); 3038 FixedDoubleArray::cast(elements())->set_the_hole(index);
3090 } 3039 }
3091 break; 3040 break;
3092 } 3041 }
3093 case EXTERNAL_PIXEL_ELEMENTS: 3042 case EXTERNAL_PIXEL_ELEMENTS:
3094 case EXTERNAL_BYTE_ELEMENTS: 3043 case EXTERNAL_BYTE_ELEMENTS:
3095 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3044 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3096 case EXTERNAL_SHORT_ELEMENTS: 3045 case EXTERNAL_SHORT_ELEMENTS:
3097 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3046 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3098 case EXTERNAL_INT_ELEMENTS: 3047 case EXTERNAL_INT_ELEMENTS:
3099 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3048 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3100 case EXTERNAL_FLOAT_ELEMENTS: 3049 case EXTERNAL_FLOAT_ELEMENTS:
3101 case EXTERNAL_DOUBLE_ELEMENTS: 3050 case EXTERNAL_DOUBLE_ELEMENTS:
3102 // Pixel and external array elements cannot be deleted. Just 3051 // Pixel and external array elements cannot be deleted. Just
3103 // silently ignore here. 3052 // silently ignore here.
3104 break; 3053 break;
3105 3054 case DICTIONARY_ELEMENTS: {
3106 case NON_STRICT_ARGUMENTS_ELEMENTS: { 3055 NumberDictionary* dictionary = element_dictionary();
3107 FixedArray* parameter_map = FixedArray::cast(elements()); 3056 int entry = dictionary->FindEntry(index);
3108 uint32_t length = parameter_map->length(); 3057 if (entry != NumberDictionary::kNotFound) {
3109 Object* probe = 3058 Object* result = dictionary->DeleteProperty(entry, mode);
3110 (index + 2) < length ? parameter_map->get(index + 2) : NULL; 3059 if (mode == STRICT_DELETION && result ==
3111 if (probe != NULL && !probe->IsTheHole()) { 3060 isolate->heap()->false_value()) {
3112 // TODO(kmillikin): We could check if this was the last aliased 3061 // In strict mode, deleting a non-configurable property throws
3113 // parameter, and revert to normal elements in that case. That 3062 // exception. dictionary->DeleteProperty will return false_value()
3114 // would enable GC of the context. 3063 // if a non-configurable property is being deleted.
3115 parameter_map->set_the_hole(index + 2); 3064 HandleScope scope;
3116 } else { 3065 Handle<Object> self(this);
3117 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 3066 Handle<Object> i = isolate->factory()->NewNumberFromUint(index);
3118 if (arguments->IsDictionary()) { 3067 Handle<Object> args[2] = { i, self };
3119 return DeleteDictionaryElement(index, mode); 3068 return isolate->Throw(*isolate->factory()->NewTypeError(
3120 } else { 3069 "strict_delete_property", HandleVector(args, 2)));
3121 return DeleteFastElement(index);
3122 } 3070 }
3123 } 3071 }
3124 break; 3072 break;
3125 } 3073 }
3074 default:
3075 UNREACHABLE();
3076 break;
3126 } 3077 }
3127 return isolate->heap()->true_value(); 3078 return isolate->heap()->true_value();
3128 } 3079 }
3129 3080
3130 3081
3131 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) { 3082 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) {
3132 Isolate* isolate = GetIsolate(); 3083 Isolate* isolate = GetIsolate();
3133 // ECMA-262, 3rd, 8.6.2.5 3084 // ECMA-262, 3rd, 8.6.2.5
3134 ASSERT(name->IsString()); 3085 ASSERT(name->IsString());
3135 3086
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
3178 { MaybeObject* maybe_obj = 3129 { MaybeObject* maybe_obj =
3179 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 3130 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
3180 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 3131 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3181 } 3132 }
3182 // Make sure the properties are normalized before removing the entry. 3133 // Make sure the properties are normalized before removing the entry.
3183 return DeleteNormalizedProperty(name, mode); 3134 return DeleteNormalizedProperty(name, mode);
3184 } 3135 }
3185 } 3136 }
3186 3137
3187 3138
3188 bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
3189 ElementsKind kind,
3190 Object* object) {
3191 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS);
3192 if (kind == FAST_ELEMENTS) {
3193 int length = IsJSArray()
3194 ? Smi::cast(JSArray::cast(this)->length())->value()
3195 : elements->length();
3196 for (int i = 0; i < length; ++i) {
3197 Object* element = elements->get(i);
3198 if (!element->IsTheHole() && element == object) return true;
3199 }
3200 } else {
3201 Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object);
3202 if (!key->IsUndefined()) return true;
3203 }
3204 return false;
3205 }
3206
3207
3208 // Check whether this object references another object. 3139 // Check whether this object references another object.
3209 bool JSObject::ReferencesObject(Object* obj) { 3140 bool JSObject::ReferencesObject(Object* obj) {
3210 Map* map_of_this = map(); 3141 Map* map_of_this = map();
3211 Heap* heap = map_of_this->heap(); 3142 Heap* heap = map_of_this->heap();
3212 AssertNoAllocation no_alloc; 3143 AssertNoAllocation no_alloc;
3213 3144
3214 // Is the object the constructor for this object? 3145 // Is the object the constructor for this object?
3215 if (map_of_this->constructor() == obj) { 3146 if (map_of_this->constructor() == obj) {
3216 return true; 3147 return true;
3217 } 3148 }
3218 3149
3219 // Is the object the prototype for this object? 3150 // Is the object the prototype for this object?
3220 if (map_of_this->prototype() == obj) { 3151 if (map_of_this->prototype() == obj) {
3221 return true; 3152 return true;
3222 } 3153 }
3223 3154
3224 // Check if the object is among the named properties. 3155 // Check if the object is among the named properties.
3225 Object* key = SlowReverseLookup(obj); 3156 Object* key = SlowReverseLookup(obj);
3226 if (!key->IsUndefined()) { 3157 if (!key->IsUndefined()) {
3227 return true; 3158 return true;
3228 } 3159 }
3229 3160
3230 // Check if the object is among the indexed properties. 3161 // Check if the object is among the indexed properties.
3231 ElementsKind kind = GetElementsKind(); 3162 switch (GetElementsKind()) {
3232 switch (kind) {
3233 case EXTERNAL_PIXEL_ELEMENTS: 3163 case EXTERNAL_PIXEL_ELEMENTS:
3234 case EXTERNAL_BYTE_ELEMENTS: 3164 case EXTERNAL_BYTE_ELEMENTS:
3235 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3165 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3236 case EXTERNAL_SHORT_ELEMENTS: 3166 case EXTERNAL_SHORT_ELEMENTS:
3237 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3167 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3238 case EXTERNAL_INT_ELEMENTS: 3168 case EXTERNAL_INT_ELEMENTS:
3239 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3169 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3240 case EXTERNAL_FLOAT_ELEMENTS: 3170 case EXTERNAL_FLOAT_ELEMENTS:
3241 case EXTERNAL_DOUBLE_ELEMENTS: 3171 case EXTERNAL_DOUBLE_ELEMENTS:
3242 case FAST_DOUBLE_ELEMENTS:
3243 // Raw pixels and external arrays do not reference other 3172 // Raw pixels and external arrays do not reference other
3244 // objects. 3173 // objects.
3245 break; 3174 break;
3246 case FAST_ELEMENTS: 3175 case FAST_ELEMENTS: {
3247 case DICTIONARY_ELEMENTS: { 3176 int length = IsJSArray() ?
3248 FixedArray* elements = FixedArray::cast(this->elements()); 3177 Smi::cast(JSArray::cast(this)->length())->value() :
3249 if (ReferencesObjectFromElements(elements, kind, obj)) return true; 3178 FixedArray::cast(elements())->length();
3179 for (int i = 0; i < length; i++) {
3180 Object* element = FixedArray::cast(elements())->get(i);
3181 if (!element->IsTheHole() && element == obj) {
3182 return true;
3183 }
3184 }
3250 break; 3185 break;
3251 } 3186 }
3252 case NON_STRICT_ARGUMENTS_ELEMENTS: { 3187 case DICTIONARY_ELEMENTS: {
3253 FixedArray* parameter_map = FixedArray::cast(elements()); 3188 key = element_dictionary()->SlowReverseLookup(obj);
3254 // Check the mapped parameters. 3189 if (!key->IsUndefined()) {
3255 int length = parameter_map->length(); 3190 return true;
3256 for (int i = 2; i < length; ++i) {
3257 Object* value = parameter_map->get(i);
3258 if (!value->IsTheHole() && value == obj) return true;
3259 } 3191 }
3260 // Check the arguments.
3261 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
3262 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : FAST_ELEMENTS;
3263 if (ReferencesObjectFromElements(arguments, kind, obj)) return true;
3264 break; 3192 break;
3265 } 3193 }
3194 default:
3195 UNREACHABLE();
3196 break;
3266 } 3197 }
3267 3198
3268 // For functions check the context. 3199 // For functions check the context.
3269 if (IsJSFunction()) { 3200 if (IsJSFunction()) {
3270 // Get the constructor function for arguments array. 3201 // Get the constructor function for arguments array.
3271 JSObject* arguments_boilerplate = 3202 JSObject* arguments_boilerplate =
3272 heap->isolate()->context()->global_context()-> 3203 heap->isolate()->context()->global_context()->
3273 arguments_boilerplate(); 3204 arguments_boilerplate();
3274 JSFunction* arguments_function = 3205 JSFunction* arguments_function =
3275 JSFunction::cast(arguments_boilerplate->map()->constructor()); 3206 JSFunction::cast(arguments_boilerplate->map()->constructor());
(...skipping 14 matching lines...) Expand all
3290 if (ctxobj->map()->constructor() == arguments_function) { 3221 if (ctxobj->map()->constructor() == arguments_function) {
3291 if (ctxobj->ReferencesObject(obj)) { 3222 if (ctxobj->ReferencesObject(obj)) {
3292 return true; 3223 return true;
3293 } 3224 }
3294 } else if (ctxobj == obj) { 3225 } else if (ctxobj == obj) {
3295 return true; 3226 return true;
3296 } 3227 }
3297 } 3228 }
3298 } 3229 }
3299 3230
3300 // Check the context extension if any. 3231 // Check the context extension (if any) if it can have references.
3301 if (context->has_extension()) { 3232 if (context->has_extension() && !context->IsCatchContext()) {
3302 return context->extension()->ReferencesObject(obj); 3233 return JSObject::cast(context->extension())->ReferencesObject(obj);
3303 } 3234 }
3304 } 3235 }
3305 3236
3306 // No references to object. 3237 // No references to object.
3307 return false; 3238 return false;
3308 } 3239 }
3309 3240
3310 3241
3311 MaybeObject* JSObject::PreventExtensions() { 3242 MaybeObject* JSObject::PreventExtensions() {
3312 Isolate* isolate = GetIsolate(); 3243 Isolate* isolate = GetIsolate();
3313 if (IsAccessCheckNeeded() && 3244 if (IsAccessCheckNeeded() &&
3314 !isolate->MayNamedAccess(this, 3245 !isolate->MayNamedAccess(this,
3315 isolate->heap()->undefined_value(), 3246 isolate->heap()->undefined_value(),
3316 v8::ACCESS_KEYS)) { 3247 v8::ACCESS_KEYS)) {
3317 isolate->ReportFailedAccessCheck(this, v8::ACCESS_KEYS); 3248 isolate->ReportFailedAccessCheck(this, v8::ACCESS_KEYS);
3318 return isolate->heap()->false_value(); 3249 return isolate->heap()->false_value();
3319 } 3250 }
3320 3251
3321 if (IsJSGlobalProxy()) { 3252 if (IsJSGlobalProxy()) {
3322 Object* proto = GetPrototype(); 3253 Object* proto = GetPrototype();
3323 if (proto->IsNull()) return this; 3254 if (proto->IsNull()) return this;
3324 ASSERT(proto->IsJSGlobalObject()); 3255 ASSERT(proto->IsJSGlobalObject());
3325 return JSObject::cast(proto)->PreventExtensions(); 3256 return JSObject::cast(proto)->PreventExtensions();
3326 } 3257 }
3327 3258
3328 // If there are fast elements we normalize. 3259 // If there are fast elements we normalize.
3329 if (HasFastElements()) { 3260 if (HasFastElements()) {
3330 MaybeObject* result = NormalizeElements(); 3261 Object* ok;
3331 if (result->IsFailure()) return result; 3262 { MaybeObject* maybe_ok = NormalizeElements();
3263 if (!maybe_ok->ToObject(&ok)) return maybe_ok;
3264 }
3332 } 3265 }
3333 // TODO(kmillikin): Handle arguments object with dictionary elements.
3334 ASSERT(HasDictionaryElements());
3335 // Make sure that we never go back to fast case. 3266 // Make sure that we never go back to fast case.
3336 element_dictionary()->set_requires_slow_elements(); 3267 element_dictionary()->set_requires_slow_elements();
3337 3268
3338 // Do a map transition, other objects with this map may still 3269 // Do a map transition, other objects with this map may still
3339 // be extensible. 3270 // be extensible.
3340 Object* new_map; 3271 Object* new_map;
3341 { MaybeObject* maybe_new_map = map()->CopyDropTransitions(); 3272 { MaybeObject* maybe_new_map = map()->CopyDropTransitions();
3342 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 3273 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
3343 } 3274 }
3344 Map::cast(new_map)->set_is_extensible(false); 3275 Map::cast(new_map)->set_is_extensible(false);
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
3481 for (Object* current = this; 3412 for (Object* current = this;
3482 current != heap->null_value(); 3413 current != heap->null_value();
3483 current = JSObject::cast(current)->GetPrototype()) { 3414 current = JSObject::cast(current)->GetPrototype()) {
3484 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); 3415 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result);
3485 if (result->IsProperty() && result->type() == CALLBACKS) return; 3416 if (result->IsProperty() && result->type() == CALLBACKS) return;
3486 } 3417 }
3487 result->NotFound(); 3418 result->NotFound();
3488 } 3419 }
3489 3420
3490 3421
3491 // Search for a getter or setter in an elements dictionary. Returns either
3492 // undefined if the element is read-only, or the getter/setter pair (fixed
3493 // array) if there is an existing one, or the hole value if the element does
3494 // not exist or is a normal non-getter/setter data element.
3495 static Object* FindGetterSetterInDictionary(NumberDictionary* dictionary,
3496 uint32_t index,
3497 Heap* heap) {
3498 int entry = dictionary->FindEntry(index);
3499 if (entry != NumberDictionary::kNotFound) {
3500 Object* result = dictionary->ValueAt(entry);
3501 PropertyDetails details = dictionary->DetailsAt(entry);
3502 if (details.IsReadOnly()) return heap->undefined_value();
3503 if (details.type() == CALLBACKS && result->IsFixedArray()) return result;
3504 }
3505 return heap->the_hole_value();
3506 }
3507
3508
3509 MaybeObject* JSObject::DefineGetterSetter(String* name, 3422 MaybeObject* JSObject::DefineGetterSetter(String* name,
3510 PropertyAttributes attributes) { 3423 PropertyAttributes attributes) {
3511 Heap* heap = GetHeap(); 3424 Heap* heap = GetHeap();
3512 // Make sure that the top context does not change when doing callbacks or 3425 // Make sure that the top context does not change when doing callbacks or
3513 // interceptor calls. 3426 // interceptor calls.
3514 AssertNoContextChange ncc; 3427 AssertNoContextChange ncc;
3515 3428
3516 // Try to flatten before operating on the string. 3429 // Try to flatten before operating on the string.
3517 name->TryFlatten(); 3430 name->TryFlatten();
3518 3431
(...skipping 10 matching lines...) Expand all
3529 break; 3442 break;
3530 case EXTERNAL_PIXEL_ELEMENTS: 3443 case EXTERNAL_PIXEL_ELEMENTS:
3531 case EXTERNAL_BYTE_ELEMENTS: 3444 case EXTERNAL_BYTE_ELEMENTS:
3532 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3445 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3533 case EXTERNAL_SHORT_ELEMENTS: 3446 case EXTERNAL_SHORT_ELEMENTS:
3534 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3447 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3535 case EXTERNAL_INT_ELEMENTS: 3448 case EXTERNAL_INT_ELEMENTS:
3536 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3449 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3537 case EXTERNAL_FLOAT_ELEMENTS: 3450 case EXTERNAL_FLOAT_ELEMENTS:
3538 case EXTERNAL_DOUBLE_ELEMENTS: 3451 case EXTERNAL_DOUBLE_ELEMENTS:
3539 case FAST_DOUBLE_ELEMENTS:
3540 // Ignore getters and setters on pixel and external array 3452 // Ignore getters and setters on pixel and external array
3541 // elements. 3453 // elements.
3542 return heap->undefined_value(); 3454 return heap->undefined_value();
3543 case DICTIONARY_ELEMENTS: { 3455 case DICTIONARY_ELEMENTS: {
3544 Object* probe = 3456 // Lookup the index.
3545 FindGetterSetterInDictionary(element_dictionary(), index, heap); 3457 NumberDictionary* dictionary = element_dictionary();
3546 if (!probe->IsTheHole()) return probe; 3458 int entry = dictionary->FindEntry(index);
3547 // Otherwise allow to override it. 3459 if (entry != NumberDictionary::kNotFound) {
3548 break; 3460 Object* result = dictionary->ValueAt(entry);
3549 } 3461 PropertyDetails details = dictionary->DetailsAt(entry);
3550 case NON_STRICT_ARGUMENTS_ELEMENTS: { 3462 if (details.IsReadOnly()) return heap->undefined_value();
3551 // Ascertain whether we have read-only properties or an existing 3463 if (details.type() == CALLBACKS) {
3552 // getter/setter pair in an arguments elements dictionary backing 3464 if (result->IsFixedArray()) {
3553 // store. 3465 return result;
3554 FixedArray* parameter_map = FixedArray::cast(elements()); 3466 }
3555 uint32_t length = parameter_map->length(); 3467 // Otherwise allow to override it.
3556 Object* probe =
3557 (index + 2) < length ? parameter_map->get(index + 2) : NULL;
3558 if (probe == NULL || probe->IsTheHole()) {
3559 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
3560 if (arguments->IsDictionary()) {
3561 NumberDictionary* dictionary = NumberDictionary::cast(arguments);
3562 probe = FindGetterSetterInDictionary(dictionary, index, heap);
3563 if (!probe->IsTheHole()) return probe;
3564 } 3468 }
3565 } 3469 }
3566 break; 3470 break;
3567 } 3471 }
3472 default:
3473 UNREACHABLE();
3474 break;
3568 } 3475 }
3569 } else { 3476 } else {
3570 // Lookup the name. 3477 // Lookup the name.
3571 LookupResult result; 3478 LookupResult result;
3572 LocalLookup(name, &result); 3479 LocalLookup(name, &result);
3573 if (result.IsProperty()) { 3480 if (result.IsProperty()) {
3574 if (result.IsReadOnly()) return heap->undefined_value(); 3481 if (result.IsReadOnly()) return heap->undefined_value();
3575 if (result.type() == CALLBACKS) { 3482 if (result.type() == CALLBACKS) {
3576 Object* obj = result.GetCallbackObject(); 3483 Object* obj = result.GetCallbackObject();
3577 // Need to preserve old getters/setters. 3484 // Need to preserve old getters/setters.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
3620 return true; 3527 return true;
3621 } 3528 }
3622 3529
3623 3530
3624 MaybeObject* JSObject::SetElementCallback(uint32_t index, 3531 MaybeObject* JSObject::SetElementCallback(uint32_t index,
3625 Object* structure, 3532 Object* structure,
3626 PropertyAttributes attributes) { 3533 PropertyAttributes attributes) {
3627 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); 3534 PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
3628 3535
3629 // Normalize elements to make this operation simple. 3536 // Normalize elements to make this operation simple.
3630 NumberDictionary* dictionary = NULL; 3537 Object* ok;
3631 { Object* result; 3538 { MaybeObject* maybe_ok = NormalizeElements();
3632 MaybeObject* maybe = NormalizeElements(); 3539 if (!maybe_ok->ToObject(&ok)) return maybe_ok;
3633 if (!maybe->ToObject(&result)) return maybe;
3634 dictionary = NumberDictionary::cast(result);
3635 } 3540 }
3636 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
3637 3541
3638 // Update the dictionary with the new CALLBACKS property. 3542 // Update the dictionary with the new CALLBACKS property.
3639 { Object* result; 3543 Object* dict;
3640 MaybeObject* maybe = dictionary->Set(index, structure, details); 3544 { MaybeObject* maybe_dict =
3641 if (!maybe->ToObject(&result)) return maybe; 3545 element_dictionary()->Set(index, structure, details);
3642 dictionary = NumberDictionary::cast(result); 3546 if (!maybe_dict->ToObject(&dict)) return maybe_dict;
3643 } 3547 }
3644 3548
3645 dictionary->set_requires_slow_elements(); 3549 NumberDictionary* elements = NumberDictionary::cast(dict);
3646 // Update the dictionary backing store on the object. 3550 elements->set_requires_slow_elements();
3647 if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) { 3551 // Set the potential new dictionary on the object.
3648 // Also delete any parameter alias. 3552 set_elements(elements);
3649 //
3650 // TODO(kmillikin): when deleting the last parameter alias we could
3651 // switch to a direct backing store without the parameter map. This
3652 // would allow GC of the context.
3653 FixedArray* parameter_map = FixedArray::cast(elements());
3654 uint32_t length = parameter_map->length();
3655 if (index + 2 < length) {
3656 parameter_map->set(index + 2, GetHeap()->the_hole_value());
3657 }
3658 parameter_map->set(1, dictionary);
3659 } else {
3660 set_elements(dictionary);
3661 }
3662 3553
3663 return structure; 3554 return structure;
3664 } 3555 }
3665 3556
3666 3557
3667 MaybeObject* JSObject::SetPropertyCallback(String* name, 3558 MaybeObject* JSObject::SetPropertyCallback(String* name,
3668 Object* structure, 3559 Object* structure,
3669 PropertyAttributes attributes) { 3560 PropertyAttributes attributes) {
3670 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); 3561 PropertyDetails details = PropertyDetails(attributes, CALLBACKS);
3671 3562
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
3778 break; 3669 break;
3779 case EXTERNAL_PIXEL_ELEMENTS: 3670 case EXTERNAL_PIXEL_ELEMENTS:
3780 case EXTERNAL_BYTE_ELEMENTS: 3671 case EXTERNAL_BYTE_ELEMENTS:
3781 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3672 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3782 case EXTERNAL_SHORT_ELEMENTS: 3673 case EXTERNAL_SHORT_ELEMENTS:
3783 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3674 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3784 case EXTERNAL_INT_ELEMENTS: 3675 case EXTERNAL_INT_ELEMENTS:
3785 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3676 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3786 case EXTERNAL_FLOAT_ELEMENTS: 3677 case EXTERNAL_FLOAT_ELEMENTS:
3787 case EXTERNAL_DOUBLE_ELEMENTS: 3678 case EXTERNAL_DOUBLE_ELEMENTS:
3788 case FAST_DOUBLE_ELEMENTS:
3789 // Ignore getters and setters on pixel and external array 3679 // Ignore getters and setters on pixel and external array
3790 // elements. 3680 // elements.
3791 return isolate->heap()->undefined_value(); 3681 return isolate->heap()->undefined_value();
3792 case DICTIONARY_ELEMENTS: 3682 case DICTIONARY_ELEMENTS:
3793 break; 3683 break;
3794 case NON_STRICT_ARGUMENTS_ELEMENTS: 3684 default:
3795 UNIMPLEMENTED(); 3685 UNREACHABLE();
3796 break; 3686 break;
3797 } 3687 }
3798 3688
3799 Object* ok; 3689 Object* ok;
3800 { MaybeObject* maybe_ok = 3690 { MaybeObject* maybe_ok =
3801 SetElementCallback(index, info, info->property_attributes()); 3691 SetElementCallback(index, info, info->property_attributes());
3802 if (!maybe_ok->ToObject(&ok)) return maybe_ok; 3692 if (!maybe_ok->ToObject(&ok)) return maybe_ok;
3803 } 3693 }
3804 } else { 3694 } else {
3805 // Lookup the name. 3695 // Lookup the name.
(...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after
4572 int pos = 0; 4462 int pos = 0;
4573 // Copy the elements from the JSArray to the temporary fixed array. 4463 // Copy the elements from the JSArray to the temporary fixed array.
4574 for (int i = 0; i < capacity; i++) { 4464 for (int i = 0; i < capacity; i++) {
4575 if (dict->IsKey(dict->KeyAt(i))) { 4465 if (dict->IsKey(dict->KeyAt(i))) {
4576 key_array->set(pos++, dict->ValueAt(i)); 4466 key_array->set(pos++, dict->ValueAt(i));
4577 } 4467 }
4578 } 4468 }
4579 // Compute the union of this and the temporary fixed array. 4469 // Compute the union of this and the temporary fixed array.
4580 return UnionOfKeys(key_array); 4470 return UnionOfKeys(key_array);
4581 } 4471 }
4582 case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: 4472 default:
4583 UNIMPLEMENTED(); 4473 UNREACHABLE();
4584 break;
4585 case JSObject::EXTERNAL_BYTE_ELEMENTS:
4586 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
4587 case JSObject::EXTERNAL_SHORT_ELEMENTS:
4588 case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
4589 case JSObject::EXTERNAL_INT_ELEMENTS:
4590 case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
4591 case JSObject::EXTERNAL_FLOAT_ELEMENTS:
4592 case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
4593 case JSObject::EXTERNAL_PIXEL_ELEMENTS:
4594 case JSObject::FAST_DOUBLE_ELEMENTS:
4595 break;
4596 } 4474 }
4597 UNREACHABLE(); 4475 UNREACHABLE();
4598 return GetHeap()->null_value(); // Failure case needs to "return" a value. 4476 return GetHeap()->null_value(); // Failure case needs to "return" a value.
4599 } 4477 }
4600 4478
4601 4479
4602 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { 4480 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) {
4603 int len0 = length(); 4481 int len0 = length();
4604 #ifdef DEBUG 4482 #ifdef DEBUG
4605 if (FLAG_enable_slow_asserts) { 4483 if (FLAG_enable_slow_asserts) {
(...skipping 2565 matching lines...) Expand 10 before | Expand all | Expand 10 after
7171 PrintF(out, "name = %s\n", name); 7049 PrintF(out, "name = %s\n", name);
7172 } 7050 }
7173 if (kind() == OPTIMIZED_FUNCTION) { 7051 if (kind() == OPTIMIZED_FUNCTION) {
7174 PrintF(out, "stack_slots = %d\n", stack_slots()); 7052 PrintF(out, "stack_slots = %d\n", stack_slots());
7175 } 7053 }
7176 7054
7177 PrintF(out, "Instructions (size = %d)\n", instruction_size()); 7055 PrintF(out, "Instructions (size = %d)\n", instruction_size());
7178 Disassembler::Decode(out, this); 7056 Disassembler::Decode(out, this);
7179 PrintF(out, "\n"); 7057 PrintF(out, "\n");
7180 7058
7181 #ifdef DEBUG
7182 if (kind() == FUNCTION) { 7059 if (kind() == FUNCTION) {
7183 DeoptimizationOutputData* data = 7060 DeoptimizationOutputData* data =
7184 DeoptimizationOutputData::cast(this->deoptimization_data()); 7061 DeoptimizationOutputData::cast(this->deoptimization_data());
7185 data->DeoptimizationOutputDataPrint(out); 7062 data->DeoptimizationOutputDataPrint(out);
7186 } else if (kind() == OPTIMIZED_FUNCTION) { 7063 } else if (kind() == OPTIMIZED_FUNCTION) {
7187 DeoptimizationInputData* data = 7064 DeoptimizationInputData* data =
7188 DeoptimizationInputData::cast(this->deoptimization_data()); 7065 DeoptimizationInputData::cast(this->deoptimization_data());
7189 data->DeoptimizationInputDataPrint(out); 7066 data->DeoptimizationInputDataPrint(out);
7190 } 7067 }
7191 PrintF("\n"); 7068 PrintF("\n");
7192 #endif
7193 7069
7194 if (kind() == OPTIMIZED_FUNCTION) { 7070 if (kind() == OPTIMIZED_FUNCTION) {
7195 SafepointTable table(this); 7071 SafepointTable table(this);
7196 PrintF(out, "Safepoints (size = %u)\n", table.size()); 7072 PrintF(out, "Safepoints (size = %u)\n", table.size());
7197 for (unsigned i = 0; i < table.length(); i++) { 7073 for (unsigned i = 0; i < table.length(); i++) {
7198 unsigned pc_offset = table.GetPcOffset(i); 7074 unsigned pc_offset = table.GetPcOffset(i);
7199 PrintF(out, "%p %4d ", (instruction_start() + pc_offset), pc_offset); 7075 PrintF(out, "%p %4d ", (instruction_start() + pc_offset), pc_offset);
7200 table.PrintEntry(i); 7076 table.PrintEntry(i);
7201 PrintF(out, " (sp -> fp)"); 7077 PrintF(out, " (sp -> fp)");
7202 SafepointEntry entry = table.GetEntry(i); 7078 SafepointEntry entry = table.GetEntry(i);
(...skipping 26 matching lines...) Expand all
7229 } 7105 }
7230 } 7106 }
7231 7107
7232 PrintF("RelocInfo (size = %d)\n", relocation_size()); 7108 PrintF("RelocInfo (size = %d)\n", relocation_size());
7233 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out); 7109 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out);
7234 PrintF(out, "\n"); 7110 PrintF(out, "\n");
7235 } 7111 }
7236 #endif // ENABLE_DISASSEMBLER 7112 #endif // ENABLE_DISASSEMBLER
7237 7113
7238 7114
7239 static void CopyFastElementsToFast(FixedArray* source,
7240 FixedArray* destination,
7241 WriteBarrierMode mode) {
7242 uint32_t count = static_cast<uint32_t>(source->length());
7243 for (uint32_t i = 0; i < count; ++i) {
7244 destination->set(i, source->get(i), mode);
7245 }
7246 }
7247
7248
7249 static void CopySlowElementsToFast(NumberDictionary* source,
7250 FixedArray* destination,
7251 WriteBarrierMode mode) {
7252 for (int i = 0; i < source->Capacity(); ++i) {
7253 Object* key = source->KeyAt(i);
7254 if (key->IsNumber()) {
7255 uint32_t entry = static_cast<uint32_t>(key->Number());
7256 destination->set(entry, source->ValueAt(i), mode);
7257 }
7258 }
7259 }
7260
7261
7262 MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity, 7115 MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity,
7263 int length) { 7116 int length) {
7264 Heap* heap = GetHeap(); 7117 Heap* heap = GetHeap();
7265 // We should never end in here with a pixel or external array. 7118 // We should never end in here with a pixel or external array.
7266 ASSERT(!HasExternalArrayElements()); 7119 ASSERT(!HasExternalArrayElements());
7267 7120
7268 // Allocate a new fast elements backing store. 7121 Object* obj;
7269 FixedArray* new_elements = NULL; 7122 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(capacity);
7270 { Object* object; 7123 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7271 MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity);
7272 if (!maybe->ToObject(&object)) return maybe;
7273 new_elements = FixedArray::cast(object);
7274 } 7124 }
7125 FixedArray* elems = FixedArray::cast(obj);
7275 7126
7276 // Find the new map to use for this object if there is a map change. 7127 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
7277 Map* new_map = NULL; 7128 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7278 if (elements()->map() != heap->non_strict_arguments_elements_map()) {
7279 Object* object;
7280 MaybeObject* maybe = map()->GetFastElementsMap();
7281 if (!maybe->ToObject(&object)) return maybe;
7282 new_map = Map::cast(object);
7283 } 7129 }
7130 Map* new_map = Map::cast(obj);
7284 7131
7285 AssertNoAllocation no_gc;
7286 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7287 switch (GetElementsKind()) { 7132 switch (GetElementsKind()) {
7288 case FAST_ELEMENTS: 7133 case FAST_ELEMENTS: {
7289 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode); 7134 AssertNoAllocation no_gc;
7290 set_map(new_map); 7135 WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc);
7291 set_elements(new_elements); 7136 FixedArray* old_elements = FixedArray::cast(elements());
7292 break; 7137 uint32_t old_length = static_cast<uint32_t>(old_elements->length());
7293 case DICTIONARY_ELEMENTS: 7138 // Fill out the new array with this content and array holes.
7294 CopySlowElementsToFast(NumberDictionary::cast(elements()), 7139 for (uint32_t i = 0; i < old_length; i++) {
7295 new_elements, 7140 elems->set(i, old_elements->get(i), mode);
7296 mode);
7297 set_map(new_map);
7298 set_elements(new_elements);
7299 break;
7300 case NON_STRICT_ARGUMENTS_ELEMENTS: {
7301 // The object's map and the parameter map are unchanged, the unaliased
7302 // arguments are copied to the new backing store.
7303 FixedArray* parameter_map = FixedArray::cast(elements());
7304 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
7305 if (arguments->IsDictionary()) {
7306 CopySlowElementsToFast(NumberDictionary::cast(arguments),
7307 new_elements,
7308 mode);
7309 } else {
7310 CopyFastElementsToFast(arguments, new_elements, mode);
7311 } 7141 }
7312 parameter_map->set(1, new_elements);
7313 break; 7142 break;
7314 } 7143 }
7315 case FAST_DOUBLE_ELEMENTS: { 7144 case FAST_DOUBLE_ELEMENTS: {
7316 FixedDoubleArray* old_elements = FixedDoubleArray::cast(elements()); 7145 FixedDoubleArray* old_elements = FixedDoubleArray::cast(elements());
7317 uint32_t old_length = static_cast<uint32_t>(old_elements->length()); 7146 uint32_t old_length = static_cast<uint32_t>(old_elements->length());
7318 // Fill out the new array with this content and array holes. 7147 // Fill out the new array with this content and array holes.
7319 for (uint32_t i = 0; i < old_length; i++) { 7148 for (uint32_t i = 0; i < old_length; i++) {
7320 if (!old_elements->is_the_hole(i)) { 7149 if (!old_elements->is_the_hole(i)) {
7321 Object* obj; 7150 Object* obj;
7322 // Objects must be allocated in the old object space, since the 7151 // Objects must be allocated in the old object space, since the
7323 // overall number of HeapNumbers needed for the conversion might 7152 // overall number of HeapNumbers needed for the conversion might
7324 // exceed the capacity of new space, and we would fail repeatedly 7153 // exceed the capacity of new space, and we would fail repeatedly
7325 // trying to convert the FixedDoubleArray. 7154 // trying to convert the FixedDoubleArray.
7326 MaybeObject* maybe_value_object = 7155 MaybeObject* maybe_value_object =
7327 GetHeap()->AllocateHeapNumber(old_elements->get(i), TENURED); 7156 GetHeap()->AllocateHeapNumber(old_elements->get(i), TENURED);
7328 if (!maybe_value_object->ToObject(&obj)) return maybe_value_object; 7157 if (!maybe_value_object->ToObject(&obj)) return maybe_value_object;
7329 // Force write barrier. It's not worth trying to exploit 7158 // Force write barrier. It's not worth trying to exploit
7330 // elems->GetWriteBarrierMode(), since it requires an 7159 // elems->GetWriteBarrierMode(), since it requires an
7331 // AssertNoAllocation stack object that would have to be positioned 7160 // AssertNoAllocation stack object that would have to be positioned
7332 // after the HeapNumber allocation anyway. 7161 // after the HeapNumber allocation anyway.
7333 new_elements->set(i, obj, UPDATE_WRITE_BARRIER); 7162 elems->set(i, obj, UPDATE_WRITE_BARRIER);
7334 } 7163 }
7335 } 7164 }
7336 break; 7165 break;
7337 } 7166 }
7338 case EXTERNAL_BYTE_ELEMENTS: 7167 case DICTIONARY_ELEMENTS: {
7339 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 7168 AssertNoAllocation no_gc;
7340 case EXTERNAL_SHORT_ELEMENTS: 7169 WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc);
7341 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 7170 NumberDictionary* dictionary = NumberDictionary::cast(elements());
7342 case EXTERNAL_INT_ELEMENTS: 7171 for (int i = 0; i < dictionary->Capacity(); i++) {
7343 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 7172 Object* key = dictionary->KeyAt(i);
7344 case EXTERNAL_FLOAT_ELEMENTS: 7173 if (key->IsNumber()) {
7345 case EXTERNAL_DOUBLE_ELEMENTS: 7174 uint32_t entry = static_cast<uint32_t>(key->Number());
7346 case EXTERNAL_PIXEL_ELEMENTS: 7175 elems->set(entry, dictionary->ValueAt(i), mode);
7176 }
7177 }
7178 break;
7179 }
7180 default:
7347 UNREACHABLE(); 7181 UNREACHABLE();
7348 break; 7182 break;
7349 } 7183 }
7350 7184
7351 // Update the length if necessary. 7185 set_map(new_map);
7186 set_elements(elems);
7187
7352 if (IsJSArray()) { 7188 if (IsJSArray()) {
7353 JSArray::cast(this)->set_length(Smi::FromInt(length)); 7189 JSArray::cast(this)->set_length(Smi::FromInt(length));
7354 } 7190 }
7355 7191
7356 return new_elements; 7192 return this;
7357 } 7193 }
7358 7194
7359 7195
7360 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( 7196 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength(
7361 int capacity, 7197 int capacity,
7362 int length) { 7198 int length) {
7363 Heap* heap = GetHeap(); 7199 Heap* heap = GetHeap();
7364 // We should never end in here with a pixel or external array. 7200 // We should never end in here with a pixel or external array.
7365 ASSERT(!HasExternalArrayElements()); 7201 ASSERT(!HasExternalArrayElements());
7366 7202
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
7410 // We should never end in here with a pixel or external array. 7246 // We should never end in here with a pixel or external array.
7411 ASSERT(!HasExternalArrayElements()); 7247 ASSERT(!HasExternalArrayElements());
7412 7248
7413 uint32_t new_length = static_cast<uint32_t>(len->Number()); 7249 uint32_t new_length = static_cast<uint32_t>(len->Number());
7414 7250
7415 switch (GetElementsKind()) { 7251 switch (GetElementsKind()) {
7416 case FAST_ELEMENTS: { 7252 case FAST_ELEMENTS: {
7417 // Make sure we never try to shrink dense arrays into sparse arrays. 7253 // Make sure we never try to shrink dense arrays into sparse arrays.
7418 ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <= 7254 ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <=
7419 new_length); 7255 new_length);
7420 MaybeObject* result = NormalizeElements(); 7256 Object* obj;
7421 if (result->IsFailure()) return result; 7257 { MaybeObject* maybe_obj = NormalizeElements();
7258 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7259 }
7422 7260
7423 // Update length for JSArrays. 7261 // Update length for JSArrays.
7424 if (IsJSArray()) JSArray::cast(this)->set_length(len); 7262 if (IsJSArray()) JSArray::cast(this)->set_length(len);
7425 break; 7263 break;
7426 } 7264 }
7427 case DICTIONARY_ELEMENTS: { 7265 case DICTIONARY_ELEMENTS: {
7428 if (IsJSArray()) { 7266 if (IsJSArray()) {
7429 uint32_t old_length = 7267 uint32_t old_length =
7430 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); 7268 static_cast<uint32_t>(JSArray::cast(this)->length()->Number());
7431 element_dictionary()->RemoveNumberEntries(new_length, old_length), 7269 element_dictionary()->RemoveNumberEntries(new_length, old_length),
7432 JSArray::cast(this)->set_length(len); 7270 JSArray::cast(this)->set_length(len);
7433 } 7271 }
7434 break; 7272 break;
7435 } 7273 }
7436 case NON_STRICT_ARGUMENTS_ELEMENTS: 7274 default:
7437 UNIMPLEMENTED();
7438 break;
7439 case EXTERNAL_BYTE_ELEMENTS:
7440 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
7441 case EXTERNAL_SHORT_ELEMENTS:
7442 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
7443 case EXTERNAL_INT_ELEMENTS:
7444 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
7445 case EXTERNAL_FLOAT_ELEMENTS:
7446 case EXTERNAL_DOUBLE_ELEMENTS:
7447 case EXTERNAL_PIXEL_ELEMENTS:
7448 case FAST_DOUBLE_ELEMENTS:
7449 UNREACHABLE(); 7275 UNREACHABLE();
7450 break; 7276 break;
7451 } 7277 }
7452 return this; 7278 return this;
7453 } 7279 }
7454 7280
7455 7281
7456 MaybeObject* JSArray::Initialize(int capacity) { 7282 MaybeObject* JSArray::Initialize(int capacity) {
7457 Heap* heap = GetHeap(); 7283 Heap* heap = GetHeap();
7458 ASSERT(capacity >= 0); 7284 ASSERT(capacity >= 0);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
7518 FixedArray::cast(elements())->set_the_hole(i); 7344 FixedArray::cast(elements())->set_the_hole(i);
7519 } 7345 }
7520 JSArray::cast(this)->set_length(Smi::cast(smi_length)); 7346 JSArray::cast(this)->set_length(Smi::cast(smi_length));
7521 } 7347 }
7522 return this; 7348 return this;
7523 } 7349 }
7524 int min = NewElementsCapacity(old_capacity); 7350 int min = NewElementsCapacity(old_capacity);
7525 int new_capacity = value > min ? value : min; 7351 int new_capacity = value > min ? value : min;
7526 if (new_capacity <= kMaxFastElementsLength || 7352 if (new_capacity <= kMaxFastElementsLength ||
7527 !ShouldConvertToSlowElements(new_capacity)) { 7353 !ShouldConvertToSlowElements(new_capacity)) {
7528 MaybeObject* result = 7354 Object* obj;
7529 SetFastElementsCapacityAndLength(new_capacity, value); 7355 { MaybeObject* maybe_obj =
7530 if (result->IsFailure()) return result; 7356 SetFastElementsCapacityAndLength(new_capacity, value);
7357 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7358 }
7531 return this; 7359 return this;
7532 } 7360 }
7533 break; 7361 break;
7534 } 7362 }
7535 case DICTIONARY_ELEMENTS: { 7363 case DICTIONARY_ELEMENTS: {
7536 if (IsJSArray()) { 7364 if (IsJSArray()) {
7537 if (value == 0) { 7365 if (value == 0) {
7538 // If the length of a slow array is reset to zero, we clear 7366 // If the length of a slow array is reset to zero, we clear
7539 // the array and flush backing storage. This has the added 7367 // the array and flush backing storage. This has the added
7540 // benefit that the array returns to fast mode. 7368 // benefit that the array returns to fast mode.
7541 Object* obj; 7369 Object* obj;
7542 { MaybeObject* maybe_obj = ResetElements(); 7370 { MaybeObject* maybe_obj = ResetElements();
7543 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 7371 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7544 } 7372 }
7545 } else { 7373 } else {
7546 // Remove deleted elements. 7374 // Remove deleted elements.
7547 uint32_t old_length = 7375 uint32_t old_length =
7548 static_cast<uint32_t>(JSArray::cast(this)->length()->Number()); 7376 static_cast<uint32_t>(JSArray::cast(this)->length()->Number());
7549 element_dictionary()->RemoveNumberEntries(value, old_length); 7377 element_dictionary()->RemoveNumberEntries(value, old_length);
7550 } 7378 }
7551 JSArray::cast(this)->set_length(Smi::cast(smi_length)); 7379 JSArray::cast(this)->set_length(Smi::cast(smi_length));
7552 } 7380 }
7553 return this; 7381 return this;
7554 } 7382 }
7555 case NON_STRICT_ARGUMENTS_ELEMENTS: 7383 default:
7556 case EXTERNAL_BYTE_ELEMENTS:
7557 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
7558 case EXTERNAL_SHORT_ELEMENTS:
7559 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
7560 case EXTERNAL_INT_ELEMENTS:
7561 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
7562 case EXTERNAL_FLOAT_ELEMENTS:
7563 case EXTERNAL_DOUBLE_ELEMENTS:
7564 case EXTERNAL_PIXEL_ELEMENTS:
7565 case FAST_DOUBLE_ELEMENTS:
7566 UNREACHABLE(); 7384 UNREACHABLE();
7567 break; 7385 break;
7568 } 7386 }
7569 } 7387 }
7570 7388
7571 // General slow case. 7389 // General slow case.
7572 if (len->IsNumber()) { 7390 if (len->IsNumber()) {
7573 uint32_t length; 7391 uint32_t length;
7574 if (len->ToArrayIndex(&length)) { 7392 if (len->ToArrayIndex(&length)) {
7575 return SetSlowElements(len); 7393 return SetSlowElements(len);
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
7752 } 7570 }
7753 break; 7571 break;
7754 } 7572 }
7755 case EXTERNAL_BYTE_ELEMENTS: 7573 case EXTERNAL_BYTE_ELEMENTS:
7756 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 7574 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
7757 case EXTERNAL_SHORT_ELEMENTS: 7575 case EXTERNAL_SHORT_ELEMENTS:
7758 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 7576 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
7759 case EXTERNAL_INT_ELEMENTS: 7577 case EXTERNAL_INT_ELEMENTS:
7760 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 7578 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
7761 case EXTERNAL_FLOAT_ELEMENTS: 7579 case EXTERNAL_FLOAT_ELEMENTS:
7762 case EXTERNAL_DOUBLE_ELEMENTS: 7580 case EXTERNAL_DOUBLE_ELEMENTS: {
7763 case FAST_DOUBLE_ELEMENTS: {
7764 ExternalArray* array = ExternalArray::cast(elements()); 7581 ExternalArray* array = ExternalArray::cast(elements());
7765 if (index < static_cast<uint32_t>(array->length())) { 7582 if (index < static_cast<uint32_t>(array->length())) {
7766 return true; 7583 return true;
7767 } 7584 }
7768 break; 7585 break;
7769 } 7586 }
7770 case DICTIONARY_ELEMENTS: { 7587 case DICTIONARY_ELEMENTS: {
7771 if (element_dictionary()->FindEntry(index) 7588 if (element_dictionary()->FindEntry(index)
7772 != NumberDictionary::kNotFound) { 7589 != NumberDictionary::kNotFound) {
7773 return true; 7590 return true;
7774 } 7591 }
7775 break; 7592 break;
7776 } 7593 }
7777 case NON_STRICT_ARGUMENTS_ELEMENTS: 7594 default:
7778 UNREACHABLE(); 7595 UNREACHABLE();
7779 break; 7596 break;
7780 } 7597 }
7781 7598
7782 // Handle [] on String objects. 7599 // Handle [] on String objects.
7783 if (this->IsStringObjectWithCharacterAt(index)) return true; 7600 if (this->IsStringObjectWithCharacterAt(index)) return true;
7784 7601
7785 Object* pt = GetPrototype(); 7602 Object* pt = GetPrototype();
7786 if (pt->IsNull()) return false; 7603 if (pt->IsNull()) return false;
7787 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); 7604 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
7881 case EXTERNAL_SHORT_ELEMENTS: 7698 case EXTERNAL_SHORT_ELEMENTS:
7882 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 7699 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
7883 case EXTERNAL_INT_ELEMENTS: 7700 case EXTERNAL_INT_ELEMENTS:
7884 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 7701 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
7885 case EXTERNAL_FLOAT_ELEMENTS: 7702 case EXTERNAL_FLOAT_ELEMENTS:
7886 case EXTERNAL_DOUBLE_ELEMENTS: { 7703 case EXTERNAL_DOUBLE_ELEMENTS: {
7887 ExternalArray* array = ExternalArray::cast(elements()); 7704 ExternalArray* array = ExternalArray::cast(elements());
7888 if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT; 7705 if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT;
7889 break; 7706 break;
7890 } 7707 }
7891 case FAST_DOUBLE_ELEMENTS:
7892 UNREACHABLE();
7893 break;
7894 case DICTIONARY_ELEMENTS: { 7708 case DICTIONARY_ELEMENTS: {
7895 if (element_dictionary()->FindEntry(index) != 7709 if (element_dictionary()->FindEntry(index) !=
7896 NumberDictionary::kNotFound) { 7710 NumberDictionary::kNotFound) {
7897 return DICTIONARY_ELEMENT; 7711 return DICTIONARY_ELEMENT;
7898 } 7712 }
7899 break; 7713 break;
7900 } 7714 }
7901 case NON_STRICT_ARGUMENTS_ELEMENTS: { 7715 default:
7902 // Aliased parameters and non-aliased elements in a fast backing store 7716 UNREACHABLE();
7903 // behave as FAST_ELEMENT. Non-aliased elements in a dictionary
7904 // backing store behave as DICTIONARY_ELEMENT.
7905 FixedArray* parameter_map = FixedArray::cast(elements());
7906 uint32_t length = parameter_map->length();
7907 Object* probe =
7908 (index + 2) < length ? parameter_map->get(index + 2) : NULL;
7909 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT;
7910 // If not aliased, check the arguments.
7911 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
7912 if (arguments->IsDictionary()) {
7913 NumberDictionary* dictionary = NumberDictionary::cast(arguments);
7914 if (dictionary->FindEntry(index) != NumberDictionary::kNotFound) {
7915 return DICTIONARY_ELEMENT;
7916 }
7917 } else {
7918 length = arguments->length();
7919 probe = (index < length) ? arguments->get(index) : NULL;
7920 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT;
7921 }
7922 break; 7717 break;
7923 }
7924 } 7718 }
7925 7719
7926 return UNDEFINED_ELEMENT; 7720 return UNDEFINED_ELEMENT;
7927 } 7721 }
7928 7722
7929 7723
7930 bool JSObject::HasElementInElements(FixedArray* elements,
7931 ElementsKind kind,
7932 uint32_t index) {
7933 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS);
7934 if (kind == FAST_ELEMENTS) {
7935 int length = IsJSArray()
7936 ? Smi::cast(JSArray::cast(this)->length())->value()
7937 : elements->length();
7938 if (index < static_cast<uint32_t>(length) &&
7939 !elements->get(index)->IsTheHole()) {
7940 return true;
7941 }
7942 } else {
7943 if (NumberDictionary::cast(elements)->FindEntry(index) !=
7944 NumberDictionary::kNotFound) {
7945 return true;
7946 }
7947 }
7948 return false;
7949 }
7950
7951
7952 bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) { 7724 bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) {
7953 // Check access rights if needed. 7725 // Check access rights if needed.
7954 if (IsAccessCheckNeeded()) { 7726 if (IsAccessCheckNeeded()) {
7955 Heap* heap = GetHeap(); 7727 Heap* heap = GetHeap();
7956 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 7728 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
7957 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); 7729 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
7958 return false; 7730 return false;
7959 } 7731 }
7960 } 7732 }
7961 7733
7962 // Check for lookup interceptor 7734 // Check for lookup interceptor
7963 if (HasIndexedInterceptor()) { 7735 if (HasIndexedInterceptor()) {
7964 return HasElementWithInterceptor(receiver, index); 7736 return HasElementWithInterceptor(receiver, index);
7965 } 7737 }
7966 7738
7967 ElementsKind kind = GetElementsKind(); 7739 switch (GetElementsKind()) {
7968 switch (kind) {
7969 case FAST_ELEMENTS: { 7740 case FAST_ELEMENTS: {
7970 uint32_t length = IsJSArray() ? 7741 uint32_t length = IsJSArray() ?
7971 static_cast<uint32_t> 7742 static_cast<uint32_t>
7972 (Smi::cast(JSArray::cast(this)->length())->value()) : 7743 (Smi::cast(JSArray::cast(this)->length())->value()) :
7973 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 7744 static_cast<uint32_t>(FixedArray::cast(elements())->length());
7974 if ((index < length) && 7745 if ((index < length) &&
7975 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true; 7746 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true;
7976 break; 7747 break;
7977 } 7748 }
7978 case EXTERNAL_PIXEL_ELEMENTS: { 7749 case EXTERNAL_PIXEL_ELEMENTS: {
(...skipping 10 matching lines...) Expand all
7989 case EXTERNAL_INT_ELEMENTS: 7760 case EXTERNAL_INT_ELEMENTS:
7990 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 7761 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
7991 case EXTERNAL_FLOAT_ELEMENTS: 7762 case EXTERNAL_FLOAT_ELEMENTS:
7992 case EXTERNAL_DOUBLE_ELEMENTS: { 7763 case EXTERNAL_DOUBLE_ELEMENTS: {
7993 ExternalArray* array = ExternalArray::cast(elements()); 7764 ExternalArray* array = ExternalArray::cast(elements());
7994 if (index < static_cast<uint32_t>(array->length())) { 7765 if (index < static_cast<uint32_t>(array->length())) {
7995 return true; 7766 return true;
7996 } 7767 }
7997 break; 7768 break;
7998 } 7769 }
7999 case FAST_DOUBLE_ELEMENTS:
8000 UNREACHABLE();
8001 break;
8002 case DICTIONARY_ELEMENTS: { 7770 case DICTIONARY_ELEMENTS: {
8003 if (element_dictionary()->FindEntry(index) 7771 if (element_dictionary()->FindEntry(index)
8004 != NumberDictionary::kNotFound) { 7772 != NumberDictionary::kNotFound) {
8005 return true; 7773 return true;
8006 } 7774 }
8007 break; 7775 break;
8008 } 7776 }
8009 case NON_STRICT_ARGUMENTS_ELEMENTS: { 7777 default:
8010 FixedArray* parameter_map = FixedArray::cast(elements()); 7778 UNREACHABLE();
8011 uint32_t length = parameter_map->length();
8012 Object* probe =
8013 (index + 2 < length) ? parameter_map->get(index + 2) : NULL;
8014 if (probe != NULL && !probe->IsTheHole()) return true;
8015
8016 // Not a mapped parameter, check the arguments.
8017 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
8018 kind = arguments->IsDictionary() ? DICTIONARY_ELEMENTS : FAST_ELEMENTS;
8019 if (HasElementInElements(arguments, kind, index)) return true;
8020 break; 7779 break;
8021 }
8022 } 7780 }
8023 7781
8024 // Handle [] on String objects. 7782 // Handle [] on String objects.
8025 if (this->IsStringObjectWithCharacterAt(index)) return true; 7783 if (this->IsStringObjectWithCharacterAt(index)) return true;
8026 7784
8027 Object* pt = GetPrototype(); 7785 Object* pt = GetPrototype();
8028 if (pt->IsNull()) return false; 7786 if (pt->IsNull()) return false;
8029 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); 7787 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index);
8030 } 7788 }
8031 7789
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
8077 7835
8078 // api style callbacks. 7836 // api style callbacks.
8079 if (structure->IsAccessorInfo()) { 7837 if (structure->IsAccessorInfo()) {
8080 Handle<AccessorInfo> data(AccessorInfo::cast(structure)); 7838 Handle<AccessorInfo> data(AccessorInfo::cast(structure));
8081 Object* fun_obj = data->getter(); 7839 Object* fun_obj = data->getter();
8082 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); 7840 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj);
8083 HandleScope scope(isolate); 7841 HandleScope scope(isolate);
8084 Handle<JSObject> self(JSObject::cast(receiver)); 7842 Handle<JSObject> self(JSObject::cast(receiver));
8085 Handle<JSObject> holder_handle(JSObject::cast(holder)); 7843 Handle<JSObject> holder_handle(JSObject::cast(holder));
8086 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); 7844 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
8087 Handle<String> key = isolate->factory()->NumberToString(number); 7845 Handle<String> key(isolate->factory()->NumberToString(number));
8088 LOG(isolate, ApiNamedPropertyAccess("load", *self, *key)); 7846 LOG(isolate, ApiNamedPropertyAccess("load", *self, *key));
8089 CustomArguments args(isolate, data->data(), *self, *holder_handle); 7847 CustomArguments args(isolate, data->data(), *self, *holder_handle);
8090 v8::AccessorInfo info(args.end()); 7848 v8::AccessorInfo info(args.end());
8091 v8::Handle<v8::Value> result; 7849 v8::Handle<v8::Value> result;
8092 { 7850 {
8093 // Leaving JavaScript. 7851 // Leaving JavaScript.
8094 VMState state(isolate, EXTERNAL); 7852 VMState state(isolate, EXTERNAL);
8095 result = call_fun(v8::Utils::ToLocal(key), info); 7853 result = call_fun(v8::Utils::ToLocal(key), info);
8096 } 7854 }
8097 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 7855 RETURN_IF_SCHEDULED_EXCEPTION(isolate);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
8172 *isolate->factory()->NewTypeError("no_setter_in_callback", 7930 *isolate->factory()->NewTypeError("no_setter_in_callback",
8173 HandleVector(args, 2))); 7931 HandleVector(args, 2)));
8174 } 7932 }
8175 } 7933 }
8176 7934
8177 UNREACHABLE(); 7935 UNREACHABLE();
8178 return NULL; 7936 return NULL;
8179 } 7937 }
8180 7938
8181 7939
8182 bool JSObject::HasFastArgumentsElements() {
8183 Heap* heap = GetHeap();
8184 if (!elements()->IsFixedArray()) return false;
8185 FixedArray* elements = FixedArray::cast(this->elements());
8186 if (elements->map() != heap->non_strict_arguments_elements_map()) {
8187 return false;
8188 }
8189 FixedArray* arguments = FixedArray::cast(elements->get(1));
8190 return !arguments->IsDictionary();
8191 }
8192
8193
8194 bool JSObject::HasDictionaryArgumentsElements() {
8195 Heap* heap = GetHeap();
8196 if (!elements()->IsFixedArray()) return false;
8197 FixedArray* elements = FixedArray::cast(this->elements());
8198 if (elements->map() != heap->non_strict_arguments_elements_map()) {
8199 return false;
8200 }
8201 FixedArray* arguments = FixedArray::cast(elements->get(1));
8202 return arguments->IsDictionary();
8203 }
8204
8205
8206 // Adding n elements in fast case is O(n*n). 7940 // Adding n elements in fast case is O(n*n).
8207 // Note: revisit design to have dual undefined values to capture absent 7941 // Note: revisit design to have dual undefined values to capture absent
8208 // elements. 7942 // elements.
8209 MaybeObject* JSObject::SetFastElement(uint32_t index, 7943 MaybeObject* JSObject::SetFastElement(uint32_t index,
8210 Object* value, 7944 Object* value,
8211 StrictModeFlag strict_mode, 7945 StrictModeFlag strict_mode,
8212 bool check_prototype) { 7946 bool check_prototype) {
8213 ASSERT(HasFastElements() || HasFastArgumentsElements()); 7947 ASSERT(HasFastElements());
8214 7948
8215 FixedArray* backing_store = FixedArray::cast(elements()); 7949 Object* elms_obj;
8216 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) { 7950 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements();
8217 backing_store = FixedArray::cast(backing_store->get(1)); 7951 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
8218 } else {
8219 Object* writable;
8220 MaybeObject* maybe = EnsureWritableFastElements();
8221 if (!maybe->ToObject(&writable)) return maybe;
8222 backing_store = FixedArray::cast(writable);
8223 } 7952 }
8224 uint32_t length = static_cast<uint32_t>(backing_store->length()); 7953 FixedArray* elms = FixedArray::cast(elms_obj);
7954 uint32_t elms_length = static_cast<uint32_t>(elms->length());
8225 7955
8226 if (check_prototype && 7956 if (check_prototype &&
8227 (index >= length || backing_store->get(index)->IsTheHole())) { 7957 (index >= elms_length || elms->get(index)->IsTheHole())) {
8228 bool found; 7958 bool found;
8229 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, 7959 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index,
8230 value, 7960 value,
8231 &found, 7961 &found,
8232 strict_mode); 7962 strict_mode);
8233 if (found) return result; 7963 if (found) return result;
8234 } 7964 }
8235 7965
8236 // Check whether there is extra space in fixed array.. 7966 // Check whether there is extra space in fixed array..
8237 if (index < length) { 7967 if (index < elms_length) {
8238 backing_store->set(index, value); 7968 elms->set(index, value);
8239 if (IsJSArray()) { 7969 if (IsJSArray()) {
8240 // Update the length of the array if needed. 7970 // Update the length of the array if needed.
8241 uint32_t array_length = 0; 7971 uint32_t array_length = 0;
8242 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); 7972 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length));
8243 if (index >= array_length) { 7973 if (index >= array_length) {
8244 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); 7974 JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
8245 } 7975 }
8246 } 7976 }
8247 return value; 7977 return value;
8248 } 7978 }
8249 7979
8250 // Allow gap in fast case. 7980 // Allow gap in fast case.
8251 if ((index - length) < kMaxGap) { 7981 if ((index - elms_length) < kMaxGap) {
8252 // Try allocating extra space. 7982 // Try allocating extra space.
8253 int new_capacity = NewElementsCapacity(index + 1); 7983 int new_capacity = NewElementsCapacity(index+1);
8254 if (new_capacity <= kMaxFastElementsLength || 7984 if (new_capacity <= kMaxFastElementsLength ||
8255 !ShouldConvertToSlowElements(new_capacity)) { 7985 !ShouldConvertToSlowElements(new_capacity)) {
8256 ASSERT(static_cast<uint32_t>(new_capacity) > index); 7986 ASSERT(static_cast<uint32_t>(new_capacity) > index);
8257 Object* new_elements; 7987 Object* obj;
8258 MaybeObject* maybe = 7988 { MaybeObject* maybe_obj =
8259 SetFastElementsCapacityAndLength(new_capacity, index + 1); 7989 SetFastElementsCapacityAndLength(new_capacity, index + 1);
8260 if (!maybe->ToObject(&new_elements)) return maybe; 7990 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8261 FixedArray::cast(new_elements)->set(index, value); 7991 }
7992 FixedArray::cast(elements())->set(index, value);
8262 return value; 7993 return value;
8263 } 7994 }
8264 } 7995 }
8265 7996
8266 // Otherwise default to slow case. 7997 // Otherwise default to slow case.
8267 MaybeObject* result = NormalizeElements(); 7998 Object* obj;
8268 if (result->IsFailure()) return result; 7999 { MaybeObject* maybe_obj = NormalizeElements();
8269 return SetDictionaryElement(index, value, strict_mode, check_prototype); 8000 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8001 }
8002 ASSERT(HasDictionaryElements());
8003 return SetElement(index, value, strict_mode, check_prototype);
8270 } 8004 }
8271 8005
8272 8006
8273 MaybeObject* JSObject::SetDictionaryElement(uint32_t index,
8274 Object* value,
8275 StrictModeFlag strict_mode,
8276 bool check_prototype) {
8277 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
8278 Isolate* isolate = GetIsolate();
8279 Heap* heap = isolate->heap();
8280
8281 // Insert element in the dictionary.
8282 FixedArray* elements = FixedArray::cast(this->elements());
8283 bool is_arguments =
8284 (elements->map() == heap->non_strict_arguments_elements_map());
8285 NumberDictionary* dictionary = NULL;
8286 if (is_arguments) {
8287 dictionary = NumberDictionary::cast(elements->get(1));
8288 } else {
8289 dictionary = NumberDictionary::cast(elements);
8290 }
8291
8292 int entry = dictionary->FindEntry(index);
8293 if (entry != NumberDictionary::kNotFound) {
8294 Object* element = dictionary->ValueAt(entry);
8295 PropertyDetails details = dictionary->DetailsAt(entry);
8296 if (details.type() == CALLBACKS) {
8297 return SetElementWithCallback(element, index, value, this, strict_mode);
8298 } else {
8299 dictionary->UpdateMaxNumberKey(index);
8300 // If put fails in strict mode, throw an exception.
8301 if (!dictionary->ValueAtPut(entry, value) && strict_mode == kStrictMode) {
8302 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
8303 Handle<Object> holder(this);
8304 Handle<Object> args[2] = { number, holder };
8305 Handle<Object> error =
8306 isolate->factory()->NewTypeError("strict_read_only_property",
8307 HandleVector(args, 2));
8308 return isolate->Throw(*error);
8309 }
8310 }
8311 } else {
8312 // Index not already used. Look for an accessor in the prototype chain.
8313 if (check_prototype) {
8314 bool found;
8315 MaybeObject* result =
8316 SetElementWithCallbackSetterInPrototypes(
8317 index, value, &found, strict_mode);
8318 if (found) return result;
8319 }
8320 // When we set the is_extensible flag to false we always force the
8321 // element into dictionary mode (and force them to stay there).
8322 if (!map()->is_extensible()) {
8323 if (strict_mode == kNonStrictMode) {
8324 return isolate->heap()->undefined_value();
8325 } else {
8326 Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
8327 Handle<String> name = isolate->factory()->NumberToString(number);
8328 Handle<Object> args[1] = { name };
8329 Handle<Object> error =
8330 isolate->factory()->NewTypeError("object_not_extensible",
8331 HandleVector(args, 1));
8332 return isolate->Throw(*error);
8333 }
8334 }
8335 Object* new_dictionary;
8336 MaybeObject* maybe = dictionary->AtNumberPut(index, value);
8337 if (!maybe->ToObject(&new_dictionary)) return maybe;
8338 if (dictionary != NumberDictionary::cast(new_dictionary)) {
8339 if (is_arguments) {
8340 elements->set(1, new_dictionary);
8341 } else {
8342 set_elements(HeapObject::cast(new_dictionary));
8343 }
8344 dictionary = NumberDictionary::cast(new_dictionary);
8345 }
8346 }
8347
8348 // Update the array length if this JSObject is an array.
8349 if (IsJSArray()) {
8350 MaybeObject* result =
8351 JSArray::cast(this)->JSArrayUpdateLengthFromIndex(index, value);
8352 if (result->IsFailure()) return result;
8353 }
8354
8355 // Attempt to put this object back in fast case.
8356 if (ShouldConvertToFastElements()) {
8357 uint32_t new_length = 0;
8358 if (IsJSArray()) {
8359 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length));
8360 } else {
8361 new_length = dictionary->max_number_key() + 1;
8362 }
8363 MaybeObject* result =
8364 SetFastElementsCapacityAndLength(new_length, new_length);
8365 if (result->IsFailure()) return result;
8366 #ifdef DEBUG
8367 if (FLAG_trace_normalization) {
8368 PrintF("Object elements are fast case again:\n");
8369 Print();
8370 }
8371 #endif
8372 }
8373 return value;
8374 }
8375
8376
8377 MUST_USE_RESULT MaybeObject* JSObject::SetFastDoubleElement( 8007 MUST_USE_RESULT MaybeObject* JSObject::SetFastDoubleElement(
8378 uint32_t index, 8008 uint32_t index,
8379 Object* value, 8009 Object* value,
8380 StrictModeFlag strict_mode, 8010 StrictModeFlag strict_mode,
8381 bool check_prototype) { 8011 bool check_prototype) {
8382 ASSERT(HasFastDoubleElements()); 8012 ASSERT(HasFastDoubleElements());
8383 8013
8384 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); 8014 FixedDoubleArray* elms = FixedDoubleArray::cast(elements());
8385 uint32_t elms_length = static_cast<uint32_t>(elms->length()); 8015 uint32_t elms_length = static_cast<uint32_t>(elms->length());
8386 8016
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
8497 } 8127 }
8498 8128
8499 8129
8500 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, 8130 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index,
8501 Object* value, 8131 Object* value,
8502 StrictModeFlag strict_mode, 8132 StrictModeFlag strict_mode,
8503 bool check_prototype) { 8133 bool check_prototype) {
8504 Isolate* isolate = GetIsolate(); 8134 Isolate* isolate = GetIsolate();
8505 switch (GetElementsKind()) { 8135 switch (GetElementsKind()) {
8506 case FAST_ELEMENTS: 8136 case FAST_ELEMENTS:
8137 // Fast case.
8507 return SetFastElement(index, value, strict_mode, check_prototype); 8138 return SetFastElement(index, value, strict_mode, check_prototype);
8508 case FAST_DOUBLE_ELEMENTS: 8139 case FAST_DOUBLE_ELEMENTS:
8509 return SetFastDoubleElement(index, value, strict_mode, check_prototype); 8140 return SetFastDoubleElement(index, value, strict_mode, check_prototype);
8510 case EXTERNAL_PIXEL_ELEMENTS: { 8141 case EXTERNAL_PIXEL_ELEMENTS: {
8511 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); 8142 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
8512 return pixels->SetValue(index, value); 8143 return pixels->SetValue(index, value);
8513 } 8144 }
8514 case EXTERNAL_BYTE_ELEMENTS: { 8145 case EXTERNAL_BYTE_ELEMENTS: {
8515 ExternalByteArray* array = ExternalByteArray::cast(elements()); 8146 ExternalByteArray* array = ExternalByteArray::cast(elements());
8516 return array->SetValue(index, value); 8147 return array->SetValue(index, value);
(...skipping 22 matching lines...) Expand all
8539 return array->SetValue(index, value); 8170 return array->SetValue(index, value);
8540 } 8171 }
8541 case EXTERNAL_FLOAT_ELEMENTS: { 8172 case EXTERNAL_FLOAT_ELEMENTS: {
8542 ExternalFloatArray* array = ExternalFloatArray::cast(elements()); 8173 ExternalFloatArray* array = ExternalFloatArray::cast(elements());
8543 return array->SetValue(index, value); 8174 return array->SetValue(index, value);
8544 } 8175 }
8545 case EXTERNAL_DOUBLE_ELEMENTS: { 8176 case EXTERNAL_DOUBLE_ELEMENTS: {
8546 ExternalDoubleArray* array = ExternalDoubleArray::cast(elements()); 8177 ExternalDoubleArray* array = ExternalDoubleArray::cast(elements());
8547 return array->SetValue(index, value); 8178 return array->SetValue(index, value);
8548 } 8179 }
8549 case DICTIONARY_ELEMENTS: 8180 case DICTIONARY_ELEMENTS: {
8550 return SetDictionaryElement(index, value, strict_mode, check_prototype); 8181 // Insert element in the dictionary.
8551 case NON_STRICT_ARGUMENTS_ELEMENTS: { 8182 FixedArray* elms = FixedArray::cast(elements());
8552 FixedArray* parameter_map = FixedArray::cast(elements()); 8183 NumberDictionary* dictionary = NumberDictionary::cast(elms);
8553 uint32_t length = parameter_map->length(); 8184
8554 Object* probe = 8185 int entry = dictionary->FindEntry(index);
8555 (index + 2 < length) ? parameter_map->get(index + 2) : NULL; 8186 if (entry != NumberDictionary::kNotFound) {
8556 if (probe != NULL && !probe->IsTheHole()) { 8187 Object* element = dictionary->ValueAt(entry);
8557 Context* context = Context::cast(parameter_map->get(0)); 8188 PropertyDetails details = dictionary->DetailsAt(entry);
8558 int context_index = Smi::cast(probe)->value(); 8189 if (details.type() == CALLBACKS) {
8559 ASSERT(!context->get(context_index)->IsTheHole()); 8190 return SetElementWithCallback(element,
8560 context->set(context_index, value); 8191 index,
8561 return value; 8192 value,
8193 this,
8194 strict_mode);
8195 } else {
8196 dictionary->UpdateMaxNumberKey(index);
8197 // If put fails instrict mode, throw exception.
8198 if (!dictionary->ValueAtPut(entry, value) &&
8199 strict_mode == kStrictMode) {
8200 Handle<Object> holder(this);
8201 Handle<Object> number(isolate->factory()->NewNumberFromUint(index));
8202 Handle<Object> args[2] = { number, holder };
8203 return isolate->Throw(
8204 *isolate->factory()->NewTypeError("strict_read_only_property",
8205 HandleVector(args, 2)));
8206 }
8207 }
8562 } else { 8208 } else {
8563 // Object is not mapped, defer to the arguments. 8209 // Index not already used. Look for an accessor in the prototype chain.
8564 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 8210 if (check_prototype) {
8565 if (arguments->IsDictionary()) { 8211 bool found;
8566 return SetDictionaryElement(index, value, strict_mode, 8212 MaybeObject* result =
8567 check_prototype); 8213 // Strict mode not needed. No-setter case already handled.
8568 } else { 8214 SetElementWithCallbackSetterInPrototypes(index,
8569 return SetFastElement(index, value, strict_mode, check_prototype); 8215 value,
8216 &found,
8217 strict_mode);
8218 if (found) return result;
8219 }
8220 // When we set the is_extensible flag to false we always force
8221 // the element into dictionary mode (and force them to stay there).
8222 if (!map()->is_extensible()) {
8223 if (strict_mode == kNonStrictMode) {
8224 return isolate->heap()->undefined_value();
8225 } else {
8226 Handle<Object> number(isolate->factory()->NewNumberFromUint(index));
8227 Handle<String> index_string(
8228 isolate->factory()->NumberToString(number));
8229 Handle<Object> args[1] = { index_string };
8230 return isolate->Throw(
8231 *isolate->factory()->NewTypeError("object_not_extensible",
8232 HandleVector(args, 1)));
8233 }
8234 }
8235 Object* result;
8236 { MaybeObject* maybe_result = dictionary->AtNumberPut(index, value);
8237 if (!maybe_result->ToObject(&result)) return maybe_result;
8238 }
8239 if (elms != FixedArray::cast(result)) {
8240 set_elements(FixedArray::cast(result));
8570 } 8241 }
8571 } 8242 }
8243
8244 // Update the array length if this JSObject is an array.
8245 if (IsJSArray()) {
8246 JSArray* array = JSArray::cast(this);
8247 Object* return_value;
8248 { MaybeObject* maybe_return_value =
8249 array->JSArrayUpdateLengthFromIndex(index, value);
8250 if (!maybe_return_value->ToObject(&return_value)) {
8251 return maybe_return_value;
8252 }
8253 }
8254 }
8255
8256 // Attempt to put this object back in fast case.
8257 if (ShouldConvertToFastElements()) {
8258 uint32_t new_length = 0;
8259 if (IsJSArray()) {
8260 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length));
8261 } else {
8262 new_length = NumberDictionary::cast(elements())->max_number_key() + 1;
8263 }
8264 if (ShouldConvertToFastDoubleElements()) {
8265 Object* obj;
8266 { MaybeObject* maybe_obj =
8267 SetFastDoubleElementsCapacityAndLength(new_length, new_length);
8268 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8269 }
8270 #ifdef DEBUG
8271 if (FLAG_trace_normalization) {
8272 PrintF("Object elements are fast double case again:\n");
8273 Print();
8274 }
8275 #endif
8276 } else {
8277 Object* obj;
8278 { MaybeObject* maybe_obj =
8279 SetFastElementsCapacityAndLength(new_length, new_length);
8280 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8281 }
8282 #ifdef DEBUG
8283 if (FLAG_trace_normalization) {
8284 PrintF("Object elements are fast case again:\n");
8285 Print();
8286 }
8287 #endif
8288 }
8289 }
8290
8291 return value;
8572 } 8292 }
8573 } 8293 }
8574 // All possible cases have been handled above. Add a return to avoid the 8294 // All possible cases have been handled above. Add a return to avoid the
8575 // complaints from the compiler. 8295 // complaints from the compiler.
8576 UNREACHABLE(); 8296 UNREACHABLE();
8577 return isolate->heap()->null_value(); 8297 return isolate->heap()->null_value();
8578 } 8298 }
8579 8299
8580 8300
8581 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, 8301 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
8642 if (details.type() == CALLBACKS) { 8362 if (details.type() == CALLBACKS) {
8643 return GetElementWithCallback(receiver, 8363 return GetElementWithCallback(receiver,
8644 element, 8364 element,
8645 index, 8365 index,
8646 this); 8366 this);
8647 } 8367 }
8648 return element; 8368 return element;
8649 } 8369 }
8650 break; 8370 break;
8651 } 8371 }
8652 case NON_STRICT_ARGUMENTS_ELEMENTS: 8372 default:
8653 UNIMPLEMENTED(); 8373 UNREACHABLE();
8654 break; 8374 break;
8655 } 8375 }
8656 8376
8657 // Continue searching via the prototype chain. 8377 // Continue searching via the prototype chain.
8658 Object* pt = GetPrototype(); 8378 Object* pt = GetPrototype();
8659 if (pt->IsNull()) return GetHeap()->undefined_value(); 8379 if (pt->IsNull()) return GetHeap()->undefined_value();
8660 return pt->GetElementWithReceiver(receiver, index); 8380 return pt->GetElementWithReceiver(receiver, index);
8661 } 8381 }
8662 8382
8663 8383
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
8755 if (details.type() == CALLBACKS) { 8475 if (details.type() == CALLBACKS) {
8756 return GetElementWithCallback(receiver, 8476 return GetElementWithCallback(receiver,
8757 element, 8477 element,
8758 index, 8478 index,
8759 this); 8479 this);
8760 } 8480 }
8761 return element; 8481 return element;
8762 } 8482 }
8763 break; 8483 break;
8764 } 8484 }
8765 case NON_STRICT_ARGUMENTS_ELEMENTS: {
8766 FixedArray* parameter_map = FixedArray::cast(elements());
8767 uint32_t length = parameter_map->length();
8768 Object* probe =
8769 (index + 2 < length) ? parameter_map->get(index + 2) : NULL;
8770 if (probe != NULL && !probe->IsTheHole()) {
8771 Context* context = Context::cast(parameter_map->get(0));
8772 int context_index = Smi::cast(probe)->value();
8773 ASSERT(!context->get(context_index)->IsTheHole());
8774 return context->get(context_index);
8775 } else {
8776 // Object is not mapped, defer to the arguments.
8777 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
8778 if (arguments->IsDictionary()) {
8779 NumberDictionary* dictionary = NumberDictionary::cast(arguments);
8780 int entry = dictionary->FindEntry(index);
8781 if (entry != NumberDictionary::kNotFound) {
8782 Object* element = dictionary->ValueAt(entry);
8783 PropertyDetails details = dictionary->DetailsAt(entry);
8784 if (details.type() == CALLBACKS) {
8785 return GetElementWithCallback(receiver,
8786 element,
8787 index,
8788 this);
8789 }
8790 return element;
8791 }
8792 } else if (index < static_cast<uint32_t>(arguments->length())) {
8793 Object* value = arguments->get(index);
8794 if (!value->IsTheHole()) return value;
8795 }
8796 }
8797 break;
8798 }
8799 } 8485 }
8800 8486
8801 Object* pt = GetPrototype(); 8487 Object* pt = GetPrototype();
8802 Heap* heap = GetHeap(); 8488 Heap* heap = GetHeap();
8803 if (pt == heap->null_value()) return heap->undefined_value(); 8489 if (pt == heap->null_value()) return heap->undefined_value();
8804 return pt->GetElementWithReceiver(receiver, index); 8490 return pt->GetElementWithReceiver(receiver, index);
8805 } 8491 }
8806 8492
8807 8493
8808 MaybeObject* JSObject::GetExternalElement(uint32_t index) { 8494 MaybeObject* JSObject::GetExternalElement(uint32_t index) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
8882 double value = array->get(index); 8568 double value = array->get(index);
8883 return GetHeap()->AllocateHeapNumber(value); 8569 return GetHeap()->AllocateHeapNumber(value);
8884 } 8570 }
8885 break; 8571 break;
8886 } 8572 }
8887 case FAST_DOUBLE_ELEMENTS: 8573 case FAST_DOUBLE_ELEMENTS:
8888 case FAST_ELEMENTS: 8574 case FAST_ELEMENTS:
8889 case DICTIONARY_ELEMENTS: 8575 case DICTIONARY_ELEMENTS:
8890 UNREACHABLE(); 8576 UNREACHABLE();
8891 break; 8577 break;
8892 case NON_STRICT_ARGUMENTS_ELEMENTS:
8893 UNIMPLEMENTED();
8894 break;
8895 } 8578 }
8896 return GetHeap()->undefined_value(); 8579 return GetHeap()->undefined_value();
8897 } 8580 }
8898 8581
8899 8582
8900 bool JSObject::HasDenseElements() { 8583 bool JSObject::HasDenseElements() {
8901 int capacity = 0; 8584 int capacity = 0;
8902 int number_of_elements = 0; 8585 int number_of_elements = 0;
8903 8586
8904 FixedArray* backing_store = FixedArray::cast(elements());
8905 switch (GetElementsKind()) { 8587 switch (GetElementsKind()) {
8906 case NON_STRICT_ARGUMENTS_ELEMENTS: 8588 case FAST_ELEMENTS: {
8907 backing_store = FixedArray::cast(backing_store->get(1)); 8589 FixedArray* elms = FixedArray::cast(elements());
8908 if (backing_store->IsDictionary()) { 8590 capacity = elms->length();
8909 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); 8591 for (int i = 0; i < capacity; i++) {
8910 capacity = dictionary->Capacity(); 8592 if (!elms->get(i)->IsTheHole()) number_of_elements++;
8911 number_of_elements = dictionary->NumberOfElements();
8912 break;
8913 } 8593 }
8914 // Fall through.
8915 case FAST_ELEMENTS:
8916 capacity = backing_store->length();
8917 for (int i = 0; i < capacity; ++i) {
8918 if (!backing_store->get(i)->IsTheHole()) ++number_of_elements;
8919 }
8920 break;
8921 case DICTIONARY_ELEMENTS: {
8922 NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
8923 capacity = dictionary->Capacity();
8924 number_of_elements = dictionary->NumberOfElements();
8925 break; 8594 break;
8926 } 8595 }
8927 case FAST_DOUBLE_ELEMENTS: { 8596 case FAST_DOUBLE_ELEMENTS: {
8928 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); 8597 FixedDoubleArray* elms = FixedDoubleArray::cast(elements());
8929 capacity = elms->length(); 8598 capacity = elms->length();
8930 for (int i = 0; i < capacity; i++) { 8599 for (int i = 0; i < capacity; i++) {
8931 if (!elms->is_the_hole(i)) number_of_elements++; 8600 if (!elms->is_the_hole(i)) number_of_elements++;
8932 } 8601 }
8933 break; 8602 break;
8934 } 8603 }
8935 case EXTERNAL_PIXEL_ELEMENTS: 8604 case EXTERNAL_PIXEL_ELEMENTS:
8936 case EXTERNAL_BYTE_ELEMENTS: 8605 case EXTERNAL_BYTE_ELEMENTS:
8937 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 8606 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
8938 case EXTERNAL_SHORT_ELEMENTS: 8607 case EXTERNAL_SHORT_ELEMENTS:
8939 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 8608 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
8940 case EXTERNAL_INT_ELEMENTS: 8609 case EXTERNAL_INT_ELEMENTS:
8941 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 8610 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
8942 case EXTERNAL_FLOAT_ELEMENTS: 8611 case EXTERNAL_FLOAT_ELEMENTS:
8943 case EXTERNAL_DOUBLE_ELEMENTS: { 8612 case EXTERNAL_DOUBLE_ELEMENTS: {
8944 return true; 8613 return true;
8945 } 8614 }
8615 case DICTIONARY_ELEMENTS: {
8616 NumberDictionary* dictionary = NumberDictionary::cast(elements());
8617 capacity = dictionary->Capacity();
8618 number_of_elements = dictionary->NumberOfElements();
8619 break;
8620 }
8621 default:
8622 UNREACHABLE();
8623 break;
8946 } 8624 }
8947 return (capacity == 0) || (number_of_elements > (capacity / 2)); 8625
8626 if (capacity == 0) return true;
8627 return (number_of_elements > (capacity / 2));
8948 } 8628 }
8949 8629
8950 8630
8951 bool JSObject::ShouldConvertToSlowElements(int new_capacity) { 8631 bool JSObject::ShouldConvertToSlowElements(int new_capacity) {
8952 // Keep the array in fast case if the current backing storage is 8632 // Keep the array in fast case if the current backing storage is
8953 // almost filled and if the new capacity is no more than twice the 8633 // almost filled and if the new capacity is no more than twice the
8954 // old capacity. 8634 // old capacity.
8955 int elements_length = 0; 8635 int elements_length = 0;
8956 if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) { 8636 if (HasFastElements()) {
8957 FixedArray* backing_store = FixedArray::cast(elements());
8958 elements_length = FixedArray::cast(backing_store->get(1))->length();
8959 } else if (HasFastElements()) {
8960 elements_length = FixedArray::cast(elements())->length(); 8637 elements_length = FixedArray::cast(elements())->length();
8961 } else if (HasFastDoubleElements()) { 8638 } else if (HasFastDoubleElements()) {
8962 elements_length = FixedDoubleArray::cast(elements())->length(); 8639 elements_length = FixedDoubleArray::cast(elements())->length();
8963 } else { 8640 } else {
8964 UNREACHABLE(); 8641 UNREACHABLE();
8965 } 8642 }
8966 return !HasDenseElements() || ((new_capacity / 2) > elements_length); 8643 return !HasDenseElements() || ((new_capacity / 2) > elements_length);
8967 } 8644 }
8968 8645
8969 8646
8970 bool JSObject::ShouldConvertToFastElements() { 8647 bool JSObject::ShouldConvertToFastElements() {
8971 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); 8648 ASSERT(HasDictionaryElements());
8649 NumberDictionary* dictionary = NumberDictionary::cast(elements());
8972 // If the elements are sparse, we should not go back to fast case. 8650 // If the elements are sparse, we should not go back to fast case.
8973 if (!HasDenseElements()) return false; 8651 if (!HasDenseElements()) return false;
8652 // If an element has been added at a very high index in the elements
8653 // dictionary, we cannot go back to fast case.
8654 if (dictionary->requires_slow_elements()) return false;
8974 // An object requiring access checks is never allowed to have fast 8655 // An object requiring access checks is never allowed to have fast
8975 // elements. If it had fast elements we would skip security checks. 8656 // elements. If it had fast elements we would skip security checks.
8976 if (IsAccessCheckNeeded()) return false; 8657 if (IsAccessCheckNeeded()) return false;
8977
8978 FixedArray* elements = FixedArray::cast(this->elements());
8979 NumberDictionary* dictionary = NULL;
8980 if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) {
8981 dictionary = NumberDictionary::cast(elements->get(1));
8982 } else {
8983 dictionary = NumberDictionary::cast(elements);
8984 }
8985 // If an element has been added at a very high index in the elements
8986 // dictionary, we cannot go back to fast case.
8987 if (dictionary->requires_slow_elements()) return false;
8988 // If the dictionary backing storage takes up roughly half as much 8658 // If the dictionary backing storage takes up roughly half as much
8989 // space as a fast-case backing storage would the array should have 8659 // space as a fast-case backing storage would the array should have
8990 // fast elements. 8660 // fast elements.
8991 uint32_t length = 0; 8661 uint32_t length = 0;
8992 if (IsJSArray()) { 8662 if (IsJSArray()) {
8993 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); 8663 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length));
8994 } else { 8664 } else {
8995 length = dictionary->max_number_key(); 8665 length = dictionary->max_number_key();
8996 } 8666 }
8997 return static_cast<uint32_t>(dictionary->Capacity()) >= 8667 return static_cast<uint32_t>(dictionary->Capacity()) >=
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
9197 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 8867 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
9198 case EXTERNAL_SHORT_ELEMENTS: 8868 case EXTERNAL_SHORT_ELEMENTS:
9199 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 8869 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
9200 case EXTERNAL_INT_ELEMENTS: 8870 case EXTERNAL_INT_ELEMENTS:
9201 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 8871 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
9202 case EXTERNAL_FLOAT_ELEMENTS: 8872 case EXTERNAL_FLOAT_ELEMENTS:
9203 case EXTERNAL_DOUBLE_ELEMENTS: { 8873 case EXTERNAL_DOUBLE_ELEMENTS: {
9204 ExternalArray* array = ExternalArray::cast(elements()); 8874 ExternalArray* array = ExternalArray::cast(elements());
9205 return index < static_cast<uint32_t>(array->length()); 8875 return index < static_cast<uint32_t>(array->length());
9206 } 8876 }
9207 case FAST_DOUBLE_ELEMENTS:
9208 UNREACHABLE();
9209 break;
9210 case DICTIONARY_ELEMENTS: { 8877 case DICTIONARY_ELEMENTS: {
9211 return element_dictionary()->FindEntry(index) 8878 return element_dictionary()->FindEntry(index)
9212 != NumberDictionary::kNotFound; 8879 != NumberDictionary::kNotFound;
9213 } 8880 }
9214 case NON_STRICT_ARGUMENTS_ELEMENTS: 8881 default:
9215 UNIMPLEMENTED(); 8882 UNREACHABLE();
9216 break; 8883 break;
9217 } 8884 }
9218 // All possibilities have been handled above already. 8885 // All possibilities have been handled above already.
9219 UNREACHABLE(); 8886 UNREACHABLE();
9220 return GetHeap()->null_value(); 8887 return GetHeap()->null_value();
9221 } 8888 }
9222 8889
9223 8890
9224 bool JSObject::HasRealNamedCallbackProperty(String* key) { 8891 bool JSObject::HasRealNamedCallbackProperty(String* key) {
9225 // Check access rights if needed. 8892 // Check access rights if needed.
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
9449 int length = ExternalArray::cast(elements())->length(); 9116 int length = ExternalArray::cast(elements())->length();
9450 while (counter < length) { 9117 while (counter < length) {
9451 if (storage != NULL) { 9118 if (storage != NULL) {
9452 storage->set(counter, Smi::FromInt(counter)); 9119 storage->set(counter, Smi::FromInt(counter));
9453 } 9120 }
9454 counter++; 9121 counter++;
9455 } 9122 }
9456 ASSERT(!storage || storage->length() >= counter); 9123 ASSERT(!storage || storage->length() >= counter);
9457 break; 9124 break;
9458 } 9125 }
9459 case FAST_DOUBLE_ELEMENTS:
9460 UNREACHABLE();
9461 break;
9462 case DICTIONARY_ELEMENTS: { 9126 case DICTIONARY_ELEMENTS: {
9463 if (storage != NULL) { 9127 if (storage != NULL) {
9464 element_dictionary()->CopyKeysTo(storage, filter); 9128 element_dictionary()->CopyKeysTo(storage, filter);
9465 } 9129 }
9466 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); 9130 counter = element_dictionary()->NumberOfElementsFilterAttributes(filter);
9467 break; 9131 break;
9468 } 9132 }
9469 case NON_STRICT_ARGUMENTS_ELEMENTS: { 9133 default:
9470 FixedArray* parameter_map = FixedArray::cast(elements()); 9134 UNREACHABLE();
9471 int length = parameter_map->length();
9472 for (int i = 2; i < length; ++i) {
9473 if (!parameter_map->get(i)->IsTheHole()) {
9474 if (storage != NULL) storage->set(i - 2, Smi::FromInt(i - 2));
9475 ++counter;
9476 }
9477 }
9478 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
9479 if (arguments->IsDictionary()) {
9480 NumberDictionary* dictionary = NumberDictionary::cast(arguments);
9481 if (storage != NULL) dictionary->CopyKeysTo(storage, filter);
9482 counter += dictionary->NumberOfElementsFilterAttributes(filter);
9483 } else {
9484 int length = arguments->length();
9485 for (int i = 0; i < length; ++i) {
9486 if (!arguments->get(i)->IsTheHole()) {
9487 if (storage != NULL) storage->set(i, Smi::FromInt(i));
9488 ++counter;
9489 }
9490 }
9491 }
9492 break; 9135 break;
9493 }
9494 } 9136 }
9495 9137
9496 if (this->IsJSValue()) { 9138 if (this->IsJSValue()) {
9497 Object* val = JSValue::cast(this)->value(); 9139 Object* val = JSValue::cast(this)->value();
9498 if (val->IsString()) { 9140 if (val->IsString()) {
9499 String* str = String::cast(val); 9141 String* str = String::cast(val);
9500 if (storage) { 9142 if (storage) {
9501 for (int i = 0; i < str->length(); i++) { 9143 for (int i = 0; i < str->length(); i++) {
9502 storage->set(counter + i, Smi::FromInt(i)); 9144 storage->set(counter + i, Smi::FromInt(i));
9503 } 9145 }
(...skipping 2060 matching lines...) Expand 10 before | Expand all | Expand 10 after
11564 if (break_point_objects()->IsUndefined()) return 0; 11206 if (break_point_objects()->IsUndefined()) return 0;
11565 // Single beak point. 11207 // Single beak point.
11566 if (!break_point_objects()->IsFixedArray()) return 1; 11208 if (!break_point_objects()->IsFixedArray()) return 1;
11567 // Multiple break points. 11209 // Multiple break points.
11568 return FixedArray::cast(break_point_objects())->length(); 11210 return FixedArray::cast(break_point_objects())->length();
11569 } 11211 }
11570 #endif 11212 #endif
11571 11213
11572 11214
11573 } } // namespace v8::internal 11215 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698