| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 239 result = call_fun(v8::Utils::ToLocal(key), info); | 239 result = call_fun(v8::Utils::ToLocal(key), info); |
| 240 } | 240 } |
| 241 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 241 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 242 if (result.IsEmpty()) { | 242 if (result.IsEmpty()) { |
| 243 return isolate->heap()->undefined_value(); | 243 return isolate->heap()->undefined_value(); |
| 244 } | 244 } |
| 245 return *v8::Utils::OpenHandle(*result); | 245 return *v8::Utils::OpenHandle(*result); |
| 246 } | 246 } |
| 247 | 247 |
| 248 // __defineGetter__ callback | 248 // __defineGetter__ callback |
| 249 if (structure->IsFixedArray()) { | 249 if (structure->IsAccessorPair()) { |
| 250 Object* getter = FixedArray::cast(structure)->get(kGetterIndex); | 250 Object* getter = AccessorPair::cast(structure)->getter(); |
| 251 if (getter->IsSpecFunction()) { | 251 if (getter->IsSpecFunction()) { |
| 252 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 252 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 253 return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter)); | 253 return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter)); |
| 254 } | 254 } |
| 255 // Getter is not a function. | 255 // Getter is not a function. |
| 256 return isolate->heap()->undefined_value(); | 256 return isolate->heap()->undefined_value(); |
| 257 } | 257 } |
| 258 | 258 |
| 259 UNREACHABLE(); | 259 UNREACHABLE(); |
| 260 return NULL; | 260 return NULL; |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 JSGlobalPropertyCell::cast( | 478 JSGlobalPropertyCell::cast( |
| 479 property_dictionary()->ValueAt(result->GetDictionaryEntry())); | 479 property_dictionary()->ValueAt(result->GetDictionaryEntry())); |
| 480 cell->set_value(value); | 480 cell->set_value(value); |
| 481 } else { | 481 } else { |
| 482 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); | 482 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); |
| 483 } | 483 } |
| 484 return value; | 484 return value; |
| 485 } | 485 } |
| 486 | 486 |
| 487 | 487 |
| 488 Handle<Object> JSObject::SetNormalizedProperty(Handle<JSObject> object, |
| 489 Handle<String> key, |
| 490 Handle<Object> value, |
| 491 PropertyDetails details) { |
| 492 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 493 object->SetNormalizedProperty(*key, *value, details), |
| 494 Object); |
| 495 } |
| 496 |
| 497 |
| 488 MaybeObject* JSObject::SetNormalizedProperty(String* name, | 498 MaybeObject* JSObject::SetNormalizedProperty(String* name, |
| 489 Object* value, | 499 Object* value, |
| 490 PropertyDetails details) { | 500 PropertyDetails details) { |
| 491 ASSERT(!HasFastProperties()); | 501 ASSERT(!HasFastProperties()); |
| 492 int entry = property_dictionary()->FindEntry(name); | 502 int entry = property_dictionary()->FindEntry(name); |
| 493 if (entry == StringDictionary::kNotFound) { | 503 if (entry == StringDictionary::kNotFound) { |
| 494 Object* store_value = value; | 504 Object* store_value = value; |
| 495 if (IsGlobalObject()) { | 505 if (IsGlobalObject()) { |
| 496 Heap* heap = name->GetHeap(); | 506 Heap* heap = name->GetHeap(); |
| 497 MaybeObject* maybe_store_value = | 507 MaybeObject* maybe_store_value = |
| (...skipping 1456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1954 MaybeObject* raw_result = | 1964 MaybeObject* raw_result = |
| 1955 this_handle->SetPropertyPostInterceptor(*name_handle, | 1965 this_handle->SetPropertyPostInterceptor(*name_handle, |
| 1956 *value_handle, | 1966 *value_handle, |
| 1957 attributes, | 1967 attributes, |
| 1958 strict_mode); | 1968 strict_mode); |
| 1959 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 1969 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 1960 return raw_result; | 1970 return raw_result; |
| 1961 } | 1971 } |
| 1962 | 1972 |
| 1963 | 1973 |
| 1974 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, |
| 1975 Handle<String> key, |
| 1976 Handle<Object> value, |
| 1977 PropertyAttributes attributes, |
| 1978 StrictModeFlag strict_mode) { |
| 1979 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 1980 object->SetProperty(*key, *value, attributes, strict_mode), |
| 1981 Object); |
| 1982 } |
| 1983 |
| 1984 |
| 1964 MaybeObject* JSReceiver::SetProperty(String* name, | 1985 MaybeObject* JSReceiver::SetProperty(String* name, |
| 1965 Object* value, | 1986 Object* value, |
| 1966 PropertyAttributes attributes, | 1987 PropertyAttributes attributes, |
| 1967 StrictModeFlag strict_mode) { | 1988 StrictModeFlag strict_mode) { |
| 1968 LookupResult result(GetIsolate()); | 1989 LookupResult result(GetIsolate()); |
| 1969 LocalLookup(name, &result); | 1990 LocalLookup(name, &result); |
| 1970 return SetProperty(&result, name, value, attributes, strict_mode); | 1991 return SetProperty(&result, name, value, attributes, strict_mode); |
| 1971 } | 1992 } |
| 1972 | 1993 |
| 1973 | 1994 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2011 // Leaving JavaScript. | 2032 // Leaving JavaScript. |
| 2012 VMState state(isolate, EXTERNAL); | 2033 VMState state(isolate, EXTERNAL); |
| 2013 call_fun(v8::Utils::ToLocal(key), | 2034 call_fun(v8::Utils::ToLocal(key), |
| 2014 v8::Utils::ToLocal(value_handle), | 2035 v8::Utils::ToLocal(value_handle), |
| 2015 info); | 2036 info); |
| 2016 } | 2037 } |
| 2017 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 2038 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 2018 return *value_handle; | 2039 return *value_handle; |
| 2019 } | 2040 } |
| 2020 | 2041 |
| 2021 if (structure->IsFixedArray()) { | 2042 if (structure->IsAccessorPair()) { |
| 2022 Object* setter = FixedArray::cast(structure)->get(kSetterIndex); | 2043 Object* setter = AccessorPair::cast(structure)->setter(); |
| 2023 if (setter->IsSpecFunction()) { | 2044 if (setter->IsSpecFunction()) { |
| 2024 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 2045 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 2025 return SetPropertyWithDefinedSetter(JSReceiver::cast(setter), value); | 2046 return SetPropertyWithDefinedSetter(JSReceiver::cast(setter), value); |
| 2026 } else { | 2047 } else { |
| 2027 if (strict_mode == kNonStrictMode) { | 2048 if (strict_mode == kNonStrictMode) { |
| 2028 return value; | 2049 return value; |
| 2029 } | 2050 } |
| 2030 Handle<String> key(name); | 2051 Handle<String> key(name); |
| 2031 Handle<Object> holder_handle(holder, isolate); | 2052 Handle<Object> holder_handle(holder, isolate); |
| 2032 Handle<Object> args[2] = { key, holder_handle }; | 2053 Handle<Object> args[2] = { key, holder_handle }; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2100 if (!maybe->To<String>(&name)) { | 2121 if (!maybe->To<String>(&name)) { |
| 2101 *found = true; // Force abort | 2122 *found = true; // Force abort |
| 2102 return maybe; | 2123 return maybe; |
| 2103 } | 2124 } |
| 2104 return JSProxy::cast(pt)->SetPropertyWithHandlerIfDefiningSetter( | 2125 return JSProxy::cast(pt)->SetPropertyWithHandlerIfDefiningSetter( |
| 2105 name, value, NONE, strict_mode, found); | 2126 name, value, NONE, strict_mode, found); |
| 2106 } | 2127 } |
| 2107 if (!JSObject::cast(pt)->HasDictionaryElements()) { | 2128 if (!JSObject::cast(pt)->HasDictionaryElements()) { |
| 2108 continue; | 2129 continue; |
| 2109 } | 2130 } |
| 2110 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary(); | 2131 SeededNumberDictionary* dictionary = |
| 2132 JSObject::cast(pt)->element_dictionary(); |
| 2111 int entry = dictionary->FindEntry(index); | 2133 int entry = dictionary->FindEntry(index); |
| 2112 if (entry != NumberDictionary::kNotFound) { | 2134 if (entry != SeededNumberDictionary::kNotFound) { |
| 2113 PropertyDetails details = dictionary->DetailsAt(entry); | 2135 PropertyDetails details = dictionary->DetailsAt(entry); |
| 2114 if (details.type() == CALLBACKS) { | 2136 if (details.type() == CALLBACKS) { |
| 2115 *found = true; | 2137 *found = true; |
| 2116 return SetElementWithCallback(dictionary->ValueAt(entry), | 2138 return SetElementWithCallback(dictionary->ValueAt(entry), |
| 2117 index, | 2139 index, |
| 2118 value, | 2140 value, |
| 2119 JSObject::cast(pt), | 2141 JSObject::cast(pt), |
| 2120 strict_mode); | 2142 strict_mode); |
| 2121 } | 2143 } |
| 2122 } | 2144 } |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2335 if (index == DescriptorLookupCache::kAbsent) { | 2357 if (index == DescriptorLookupCache::kAbsent) { |
| 2336 index = descriptors->Search(sentinel_name); | 2358 index = descriptors->Search(sentinel_name); |
| 2337 cache->Update(descriptors, sentinel_name, index); | 2359 cache->Update(descriptors, sentinel_name, index); |
| 2338 } | 2360 } |
| 2339 // If the transition already exists, return its descriptor. | 2361 // If the transition already exists, return its descriptor. |
| 2340 if (index != DescriptorArray::kNotFound) { | 2362 if (index != DescriptorArray::kNotFound) { |
| 2341 PropertyDetails details(descriptors->GetDetails(index)); | 2363 PropertyDetails details(descriptors->GetDetails(index)); |
| 2342 if (details.type() == ELEMENTS_TRANSITION) { | 2364 if (details.type() == ELEMENTS_TRANSITION) { |
| 2343 return descriptors->GetValue(index); | 2365 return descriptors->GetValue(index); |
| 2344 } else { | 2366 } else { |
| 2345 *safe_to_add_transition = false; | 2367 if (safe_to_add_transition != NULL) { |
| 2368 *safe_to_add_transition = false; |
| 2369 } |
| 2346 } | 2370 } |
| 2347 } | 2371 } |
| 2348 return NULL; | 2372 return NULL; |
| 2349 } | 2373 } |
| 2350 | 2374 |
| 2351 | 2375 |
| 2352 Map* Map::LookupElementsTransitionMap(ElementsKind elements_kind, | 2376 Map* Map::LookupElementsTransitionMap(ElementsKind elements_kind, |
| 2353 bool* safe_to_add_transition) { | 2377 bool* safe_to_add_transition) { |
| 2354 // Special case: indirect SMI->FAST transition (cf. comment in | 2378 // Special case: indirect SMI->FAST transition (cf. comment in |
| 2355 // AddElementsTransition()). | 2379 // AddElementsTransition()). |
| (...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3017 | 3041 |
| 3018 // Set a real local property, even if it is READ_ONLY. If the property is not | 3042 // Set a real local property, even if it is READ_ONLY. If the property is not |
| 3019 // present, add it with attributes NONE. This code is an exact clone of | 3043 // present, add it with attributes NONE. This code is an exact clone of |
| 3020 // SetProperty, with the check for IsReadOnly and the check for a | 3044 // SetProperty, with the check for IsReadOnly and the check for a |
| 3021 // callback setter removed. The two lines looking up the LookupResult | 3045 // callback setter removed. The two lines looking up the LookupResult |
| 3022 // result are also added. If one of the functions is changed, the other | 3046 // result are also added. If one of the functions is changed, the other |
| 3023 // should be. | 3047 // should be. |
| 3024 // Note that this method cannot be used to set the prototype of a function | 3048 // Note that this method cannot be used to set the prototype of a function |
| 3025 // because ConvertDescriptorToField() which is called in "case CALLBACKS:" | 3049 // because ConvertDescriptorToField() which is called in "case CALLBACKS:" |
| 3026 // doesn't handle function prototypes correctly. | 3050 // doesn't handle function prototypes correctly. |
| 3051 Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes( |
| 3052 Handle<JSObject> object, |
| 3053 Handle<String> key, |
| 3054 Handle<Object> value, |
| 3055 PropertyAttributes attributes) { |
| 3056 CALL_HEAP_FUNCTION( |
| 3057 object->GetIsolate(), |
| 3058 object->SetLocalPropertyIgnoreAttributes(*key, *value, attributes), |
| 3059 Object); |
| 3060 } |
| 3061 |
| 3062 |
| 3027 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( | 3063 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
| 3028 String* name, | 3064 String* name, |
| 3029 Object* value, | 3065 Object* value, |
| 3030 PropertyAttributes attributes) { | 3066 PropertyAttributes attributes) { |
| 3031 | 3067 |
| 3032 // Make sure that the top context does not change when doing callbacks or | 3068 // Make sure that the top context does not change when doing callbacks or |
| 3033 // interceptor calls. | 3069 // interceptor calls. |
| 3034 AssertNoContextChange ncc; | 3070 AssertNoContextChange ncc; |
| 3035 Isolate* isolate = GetIsolate(); | 3071 Isolate* isolate = GetIsolate(); |
| 3036 LookupResult result(isolate); | 3072 LookupResult result(isolate); |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3307 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 3343 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 3308 } | 3344 } |
| 3309 GetIsolate()->counters()->normalized_maps()->Increment(); | 3345 GetIsolate()->counters()->normalized_maps()->Increment(); |
| 3310 | 3346 |
| 3311 set_map(Map::cast(obj)); | 3347 set_map(Map::cast(obj)); |
| 3312 } | 3348 } |
| 3313 return map()->UpdateCodeCache(name, code); | 3349 return map()->UpdateCodeCache(name, code); |
| 3314 } | 3350 } |
| 3315 | 3351 |
| 3316 | 3352 |
| 3353 void JSObject::NormalizeProperties(Handle<JSObject> object, |
| 3354 PropertyNormalizationMode mode, |
| 3355 int expected_additional_properties) { |
| 3356 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), |
| 3357 object->NormalizeProperties( |
| 3358 mode, expected_additional_properties)); |
| 3359 } |
| 3360 |
| 3361 |
| 3317 MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, | 3362 MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, |
| 3318 int expected_additional_properties) { | 3363 int expected_additional_properties) { |
| 3319 if (!HasFastProperties()) return this; | 3364 if (!HasFastProperties()) return this; |
| 3320 | 3365 |
| 3321 // The global object is always normalized. | 3366 // The global object is always normalized. |
| 3322 ASSERT(!IsGlobalObject()); | 3367 ASSERT(!IsGlobalObject()); |
| 3323 // JSGlobalProxy must never be normalized | 3368 // JSGlobalProxy must never be normalized |
| 3324 ASSERT(!IsJSGlobalProxy()); | 3369 ASSERT(!IsJSGlobalProxy()); |
| 3325 | 3370 |
| 3326 Map* map_of_this = map(); | 3371 Map* map_of_this = map(); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3429 #ifdef DEBUG | 3474 #ifdef DEBUG |
| 3430 if (FLAG_trace_normalization) { | 3475 if (FLAG_trace_normalization) { |
| 3431 PrintF("Object properties have been normalized:\n"); | 3476 PrintF("Object properties have been normalized:\n"); |
| 3432 Print(); | 3477 Print(); |
| 3433 } | 3478 } |
| 3434 #endif | 3479 #endif |
| 3435 return this; | 3480 return this; |
| 3436 } | 3481 } |
| 3437 | 3482 |
| 3438 | 3483 |
| 3484 void JSObject::TransformToFastProperties(Handle<JSObject> object, |
| 3485 int unused_property_fields) { |
| 3486 CALL_HEAP_FUNCTION_VOID( |
| 3487 object->GetIsolate(), |
| 3488 object->TransformToFastProperties(unused_property_fields)); |
| 3489 } |
| 3490 |
| 3491 |
| 3439 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) { | 3492 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) { |
| 3440 if (HasFastProperties()) return this; | 3493 if (HasFastProperties()) return this; |
| 3441 ASSERT(!IsGlobalObject()); | 3494 ASSERT(!IsGlobalObject()); |
| 3442 return property_dictionary()-> | 3495 return property_dictionary()-> |
| 3443 TransformPropertiesToFastFor(this, unused_property_fields); | 3496 TransformPropertiesToFastFor(this, unused_property_fields); |
| 3444 } | 3497 } |
| 3445 | 3498 |
| 3446 | 3499 |
| 3500 Handle<SeededNumberDictionary> JSObject::NormalizeElements( |
| 3501 Handle<JSObject> object) { |
| 3502 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 3503 object->NormalizeElements(), |
| 3504 SeededNumberDictionary); |
| 3505 } |
| 3506 |
| 3507 |
| 3447 MaybeObject* JSObject::NormalizeElements() { | 3508 MaybeObject* JSObject::NormalizeElements() { |
| 3448 ASSERT(!HasExternalArrayElements()); | 3509 ASSERT(!HasExternalArrayElements()); |
| 3449 | 3510 |
| 3450 // Find the backing store. | 3511 // Find the backing store. |
| 3451 FixedArrayBase* array = FixedArrayBase::cast(elements()); | 3512 FixedArrayBase* array = FixedArrayBase::cast(elements()); |
| 3452 Map* old_map = array->map(); | 3513 Map* old_map = array->map(); |
| 3453 bool is_arguments = | 3514 bool is_arguments = |
| 3454 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map()); | 3515 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map()); |
| 3455 if (is_arguments) { | 3516 if (is_arguments) { |
| 3456 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); | 3517 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); |
| 3457 } | 3518 } |
| 3458 if (array->IsDictionary()) return array; | 3519 if (array->IsDictionary()) return array; |
| 3459 | 3520 |
| 3460 ASSERT(HasFastElements() || | 3521 ASSERT(HasFastElements() || |
| 3461 HasFastSmiOnlyElements() || | 3522 HasFastSmiOnlyElements() || |
| 3462 HasFastDoubleElements() || | 3523 HasFastDoubleElements() || |
| 3463 HasFastArgumentsElements()); | 3524 HasFastArgumentsElements()); |
| 3464 // Compute the effective length and allocate a new backing store. | 3525 // Compute the effective length and allocate a new backing store. |
| 3465 int length = IsJSArray() | 3526 int length = IsJSArray() |
| 3466 ? Smi::cast(JSArray::cast(this)->length())->value() | 3527 ? Smi::cast(JSArray::cast(this)->length())->value() |
| 3467 : array->length(); | 3528 : array->length(); |
| 3468 int old_capacity = 0; | 3529 int old_capacity = 0; |
| 3469 int used_elements = 0; | 3530 int used_elements = 0; |
| 3470 GetElementsCapacityAndUsage(&old_capacity, &used_elements); | 3531 GetElementsCapacityAndUsage(&old_capacity, &used_elements); |
| 3471 NumberDictionary* dictionary = NULL; | 3532 SeededNumberDictionary* dictionary = NULL; |
| 3472 { Object* object; | 3533 { Object* object; |
| 3473 MaybeObject* maybe = NumberDictionary::Allocate(used_elements); | 3534 MaybeObject* maybe = SeededNumberDictionary::Allocate(used_elements); |
| 3474 if (!maybe->ToObject(&object)) return maybe; | 3535 if (!maybe->ToObject(&object)) return maybe; |
| 3475 dictionary = NumberDictionary::cast(object); | 3536 dictionary = SeededNumberDictionary::cast(object); |
| 3476 } | 3537 } |
| 3477 | 3538 |
| 3478 // Copy the elements to the new backing store. | 3539 // Copy the elements to the new backing store. |
| 3479 bool has_double_elements = array->IsFixedDoubleArray(); | 3540 bool has_double_elements = array->IsFixedDoubleArray(); |
| 3480 for (int i = 0; i < length; i++) { | 3541 for (int i = 0; i < length; i++) { |
| 3481 Object* value = NULL; | 3542 Object* value = NULL; |
| 3482 if (has_double_elements) { | 3543 if (has_double_elements) { |
| 3483 FixedDoubleArray* double_array = FixedDoubleArray::cast(array); | 3544 FixedDoubleArray* double_array = FixedDoubleArray::cast(array); |
| 3484 if (double_array->is_the_hole(i)) { | 3545 if (double_array->is_the_hole(i)) { |
| 3485 value = GetIsolate()->heap()->the_hole_value(); | 3546 value = GetIsolate()->heap()->the_hole_value(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3496 ASSERT(old_map->has_fast_elements() || | 3557 ASSERT(old_map->has_fast_elements() || |
| 3497 old_map->has_fast_smi_only_elements()); | 3558 old_map->has_fast_smi_only_elements()); |
| 3498 value = FixedArray::cast(array)->get(i); | 3559 value = FixedArray::cast(array)->get(i); |
| 3499 } | 3560 } |
| 3500 PropertyDetails details = PropertyDetails(NONE, NORMAL); | 3561 PropertyDetails details = PropertyDetails(NONE, NORMAL); |
| 3501 if (!value->IsTheHole()) { | 3562 if (!value->IsTheHole()) { |
| 3502 Object* result; | 3563 Object* result; |
| 3503 MaybeObject* maybe_result = | 3564 MaybeObject* maybe_result = |
| 3504 dictionary->AddNumberEntry(i, value, details); | 3565 dictionary->AddNumberEntry(i, value, details); |
| 3505 if (!maybe_result->ToObject(&result)) return maybe_result; | 3566 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 3506 dictionary = NumberDictionary::cast(result); | 3567 dictionary = SeededNumberDictionary::cast(result); |
| 3507 } | 3568 } |
| 3508 } | 3569 } |
| 3509 | 3570 |
| 3510 // Switch to using the dictionary as the backing storage for elements. | 3571 // Switch to using the dictionary as the backing storage for elements. |
| 3511 if (is_arguments) { | 3572 if (is_arguments) { |
| 3512 FixedArray::cast(elements())->set(1, dictionary); | 3573 FixedArray::cast(elements())->set(1, dictionary); |
| 3513 } else { | 3574 } else { |
| 3514 // Set the new map first to satify the elements type assert in | 3575 // Set the new map first to satify the elements type assert in |
| 3515 // set_elements(). | 3576 // set_elements(). |
| 3516 Object* new_map; | 3577 Object* new_map; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3553 | 3614 |
| 3554 | 3615 |
| 3555 MaybeObject* JSObject::SetIdentityHash(Object* hash, CreationFlag flag) { | 3616 MaybeObject* JSObject::SetIdentityHash(Object* hash, CreationFlag flag) { |
| 3556 MaybeObject* maybe = SetHiddenProperty(GetHeap()->identity_hash_symbol(), | 3617 MaybeObject* maybe = SetHiddenProperty(GetHeap()->identity_hash_symbol(), |
| 3557 hash); | 3618 hash); |
| 3558 if (maybe->IsFailure()) return maybe; | 3619 if (maybe->IsFailure()) return maybe; |
| 3559 return this; | 3620 return this; |
| 3560 } | 3621 } |
| 3561 | 3622 |
| 3562 | 3623 |
| 3624 int JSObject::GetIdentityHash(Handle<JSObject> obj) { |
| 3625 CALL_AND_RETRY(obj->GetIsolate(), |
| 3626 obj->GetIdentityHash(ALLOW_CREATION), |
| 3627 return Smi::cast(__object__)->value(), |
| 3628 return 0); |
| 3629 } |
| 3630 |
| 3631 |
| 3563 MaybeObject* JSObject::GetIdentityHash(CreationFlag flag) { | 3632 MaybeObject* JSObject::GetIdentityHash(CreationFlag flag) { |
| 3564 Object* stored_value = GetHiddenProperty(GetHeap()->identity_hash_symbol()); | 3633 Object* stored_value = GetHiddenProperty(GetHeap()->identity_hash_symbol()); |
| 3565 if (stored_value->IsSmi()) return stored_value; | 3634 if (stored_value->IsSmi()) return stored_value; |
| 3566 | 3635 |
| 3567 // Do not generate permanent identity hash code if not requested. | 3636 // Do not generate permanent identity hash code if not requested. |
| 3568 if (flag == OMIT_CREATION) return GetHeap()->undefined_value(); | 3637 if (flag == OMIT_CREATION) return GetHeap()->undefined_value(); |
| 3569 | 3638 |
| 3570 Smi* hash = GenerateIdentityHash(); | 3639 Smi* hash = GenerateIdentityHash(); |
| 3571 MaybeObject* result = SetHiddenProperty(GetHeap()->identity_hash_symbol(), | 3640 MaybeObject* result = SetHiddenProperty(GetHeap()->identity_hash_symbol(), |
| 3572 hash); | 3641 hash); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3605 return GetHeap()->undefined_value(); | 3674 return GetHeap()->undefined_value(); |
| 3606 } | 3675 } |
| 3607 StringDictionary* dictionary = | 3676 StringDictionary* dictionary = |
| 3608 StringDictionary::cast(hidden_lookup->ToObjectUnchecked()); | 3677 StringDictionary::cast(hidden_lookup->ToObjectUnchecked()); |
| 3609 int entry = dictionary->FindEntry(key); | 3678 int entry = dictionary->FindEntry(key); |
| 3610 if (entry == StringDictionary::kNotFound) return GetHeap()->undefined_value(); | 3679 if (entry == StringDictionary::kNotFound) return GetHeap()->undefined_value(); |
| 3611 return dictionary->ValueAt(entry); | 3680 return dictionary->ValueAt(entry); |
| 3612 } | 3681 } |
| 3613 | 3682 |
| 3614 | 3683 |
| 3684 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> obj, |
| 3685 Handle<String> key, |
| 3686 Handle<Object> value) { |
| 3687 CALL_HEAP_FUNCTION(obj->GetIsolate(), |
| 3688 obj->SetHiddenProperty(*key, *value), |
| 3689 Object); |
| 3690 } |
| 3691 |
| 3692 |
| 3615 MaybeObject* JSObject::SetHiddenProperty(String* key, Object* value) { | 3693 MaybeObject* JSObject::SetHiddenProperty(String* key, Object* value) { |
| 3616 if (IsJSGlobalProxy()) { | 3694 if (IsJSGlobalProxy()) { |
| 3617 // For a proxy, use the prototype as target object. | 3695 // For a proxy, use the prototype as target object. |
| 3618 Object* proxy_parent = GetPrototype(); | 3696 Object* proxy_parent = GetPrototype(); |
| 3619 // If the proxy is detached, return undefined. | 3697 // If the proxy is detached, return undefined. |
| 3620 if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); | 3698 if (proxy_parent->IsNull()) return GetHeap()->undefined_value(); |
| 3621 ASSERT(proxy_parent->IsJSGlobalObject()); | 3699 ASSERT(proxy_parent->IsJSGlobalObject()); |
| 3622 return JSObject::cast(proxy_parent)->SetHiddenProperty(key, value); | 3700 return JSObject::cast(proxy_parent)->SetHiddenProperty(key, value); |
| 3623 } | 3701 } |
| 3624 ASSERT(!IsJSGlobalProxy()); | 3702 ASSERT(!IsJSGlobalProxy()); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3832 } | 3910 } |
| 3833 MaybeObject* raw_result = this_handle->GetElementsAccessor()->Delete( | 3911 MaybeObject* raw_result = this_handle->GetElementsAccessor()->Delete( |
| 3834 *this_handle, | 3912 *this_handle, |
| 3835 index, | 3913 index, |
| 3836 NORMAL_DELETION); | 3914 NORMAL_DELETION); |
| 3837 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 3915 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 3838 return raw_result; | 3916 return raw_result; |
| 3839 } | 3917 } |
| 3840 | 3918 |
| 3841 | 3919 |
| 3920 Handle<Object> JSObject::DeleteElement(Handle<JSObject> obj, |
| 3921 uint32_t index) { |
| 3922 CALL_HEAP_FUNCTION(obj->GetIsolate(), |
| 3923 obj->DeleteElement(index, JSObject::NORMAL_DELETION), |
| 3924 Object); |
| 3925 } |
| 3926 |
| 3927 |
| 3842 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { | 3928 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { |
| 3843 Isolate* isolate = GetIsolate(); | 3929 Isolate* isolate = GetIsolate(); |
| 3844 // Check access rights if needed. | 3930 // Check access rights if needed. |
| 3845 if (IsAccessCheckNeeded() && | 3931 if (IsAccessCheckNeeded() && |
| 3846 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { | 3932 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { |
| 3847 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); | 3933 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); |
| 3848 return isolate->heap()->false_value(); | 3934 return isolate->heap()->false_value(); |
| 3849 } | 3935 } |
| 3850 | 3936 |
| 3851 if (IsJSGlobalProxy()) { | 3937 if (IsJSGlobalProxy()) { |
| 3852 Object* proto = GetPrototype(); | 3938 Object* proto = GetPrototype(); |
| 3853 if (proto->IsNull()) return isolate->heap()->false_value(); | 3939 if (proto->IsNull()) return isolate->heap()->false_value(); |
| 3854 ASSERT(proto->IsJSGlobalObject()); | 3940 ASSERT(proto->IsJSGlobalObject()); |
| 3855 return JSGlobalObject::cast(proto)->DeleteElement(index, mode); | 3941 return JSGlobalObject::cast(proto)->DeleteElement(index, mode); |
| 3856 } | 3942 } |
| 3857 | 3943 |
| 3858 if (HasIndexedInterceptor()) { | 3944 if (HasIndexedInterceptor()) { |
| 3859 // Skip interceptor if forcing deletion. | 3945 // Skip interceptor if forcing deletion. |
| 3860 if (mode != FORCE_DELETION) { | 3946 if (mode != FORCE_DELETION) { |
| 3861 return DeleteElementWithInterceptor(index); | 3947 return DeleteElementWithInterceptor(index); |
| 3862 } | 3948 } |
| 3863 mode = JSReceiver::FORCE_DELETION; | 3949 mode = JSReceiver::FORCE_DELETION; |
| 3864 } | 3950 } |
| 3865 | 3951 |
| 3866 return GetElementsAccessor()->Delete(this, index, mode); | 3952 return GetElementsAccessor()->Delete(this, index, mode); |
| 3867 } | 3953 } |
| 3868 | 3954 |
| 3869 | 3955 |
| 3870 MaybeObject* JSReceiver::DeleteProperty(String* name, DeleteMode mode) { | 3956 Handle<Object> JSObject::DeleteProperty(Handle<JSObject> obj, |
| 3871 if (IsJSProxy()) { | 3957 Handle<String> prop) { |
| 3872 return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode); | 3958 CALL_HEAP_FUNCTION(obj->GetIsolate(), |
| 3873 } | 3959 obj->DeleteProperty(*prop, JSObject::NORMAL_DELETION), |
| 3874 return JSObject::cast(this)->DeleteProperty(name, mode); | 3960 Object); |
| 3875 } | |
| 3876 | |
| 3877 | |
| 3878 MaybeObject* JSReceiver::DeleteElement(uint32_t index, DeleteMode mode) { | |
| 3879 if (IsJSProxy()) { | |
| 3880 return JSProxy::cast(this)->DeleteElementWithHandler(index, mode); | |
| 3881 } | |
| 3882 return JSObject::cast(this)->DeleteElement(index, mode); | |
| 3883 } | 3961 } |
| 3884 | 3962 |
| 3885 | 3963 |
| 3886 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) { | 3964 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) { |
| 3887 Isolate* isolate = GetIsolate(); | 3965 Isolate* isolate = GetIsolate(); |
| 3888 // ECMA-262, 3rd, 8.6.2.5 | 3966 // ECMA-262, 3rd, 8.6.2.5 |
| 3889 ASSERT(name->IsString()); | 3967 ASSERT(name->IsString()); |
| 3890 | 3968 |
| 3891 // Check access rights if needed. | 3969 // Check access rights if needed. |
| 3892 if (IsAccessCheckNeeded() && | 3970 if (IsAccessCheckNeeded() && |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3933 { MaybeObject* maybe_obj = | 4011 { MaybeObject* maybe_obj = |
| 3934 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 4012 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 3935 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 4013 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 3936 } | 4014 } |
| 3937 // Make sure the properties are normalized before removing the entry. | 4015 // Make sure the properties are normalized before removing the entry. |
| 3938 return DeleteNormalizedProperty(name, mode); | 4016 return DeleteNormalizedProperty(name, mode); |
| 3939 } | 4017 } |
| 3940 } | 4018 } |
| 3941 | 4019 |
| 3942 | 4020 |
| 4021 MaybeObject* JSReceiver::DeleteElement(uint32_t index, DeleteMode mode) { |
| 4022 if (IsJSProxy()) { |
| 4023 return JSProxy::cast(this)->DeleteElementWithHandler(index, mode); |
| 4024 } |
| 4025 return JSObject::cast(this)->DeleteElement(index, mode); |
| 4026 } |
| 4027 |
| 4028 |
| 4029 MaybeObject* JSReceiver::DeleteProperty(String* name, DeleteMode mode) { |
| 4030 if (IsJSProxy()) { |
| 4031 return JSProxy::cast(this)->DeletePropertyWithHandler(name, mode); |
| 4032 } |
| 4033 return JSObject::cast(this)->DeleteProperty(name, mode); |
| 4034 } |
| 4035 |
| 4036 |
| 3943 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 4037 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
| 3944 ElementsKind kind, | 4038 ElementsKind kind, |
| 3945 Object* object) { | 4039 Object* object) { |
| 3946 ASSERT(kind == FAST_ELEMENTS || | 4040 ASSERT(kind == FAST_ELEMENTS || |
| 3947 kind == DICTIONARY_ELEMENTS); | 4041 kind == DICTIONARY_ELEMENTS); |
| 3948 if (kind == FAST_ELEMENTS) { | 4042 if (kind == FAST_ELEMENTS) { |
| 3949 int length = IsJSArray() | 4043 int length = IsJSArray() |
| 3950 ? Smi::cast(JSArray::cast(this)->length())->value() | 4044 ? Smi::cast(JSArray::cast(this)->length())->value() |
| 3951 : elements->length(); | 4045 : elements->length(); |
| 3952 for (int i = 0; i < length; ++i) { | 4046 for (int i = 0; i < length; ++i) { |
| 3953 Object* element = elements->get(i); | 4047 Object* element = elements->get(i); |
| 3954 if (!element->IsTheHole() && element == object) return true; | 4048 if (!element->IsTheHole() && element == object) return true; |
| 3955 } | 4049 } |
| 3956 } else { | 4050 } else { |
| 3957 Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object); | 4051 Object* key = |
| 4052 SeededNumberDictionary::cast(elements)->SlowReverseLookup(object); |
| 3958 if (!key->IsUndefined()) return true; | 4053 if (!key->IsUndefined()) return true; |
| 3959 } | 4054 } |
| 3960 return false; | 4055 return false; |
| 3961 } | 4056 } |
| 3962 | 4057 |
| 3963 | 4058 |
| 3964 // Check whether this object references another object. | 4059 // Check whether this object references another object. |
| 3965 bool JSObject::ReferencesObject(Object* obj) { | 4060 bool JSObject::ReferencesObject(Object* obj) { |
| 3966 Map* map_of_this = map(); | 4061 Map* map_of_this = map(); |
| 3967 Heap* heap = GetHeap(); | 4062 Heap* heap = GetHeap(); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4059 if (context->has_extension() && !context->IsCatchContext()) { | 4154 if (context->has_extension() && !context->IsCatchContext()) { |
| 4060 return JSObject::cast(context->extension())->ReferencesObject(obj); | 4155 return JSObject::cast(context->extension())->ReferencesObject(obj); |
| 4061 } | 4156 } |
| 4062 } | 4157 } |
| 4063 | 4158 |
| 4064 // No references to object. | 4159 // No references to object. |
| 4065 return false; | 4160 return false; |
| 4066 } | 4161 } |
| 4067 | 4162 |
| 4068 | 4163 |
| 4164 Handle<Object> JSObject::PreventExtensions(Handle<JSObject> object) { |
| 4165 CALL_HEAP_FUNCTION(object->GetIsolate(), object->PreventExtensions(), Object); |
| 4166 } |
| 4167 |
| 4168 |
| 4069 MaybeObject* JSObject::PreventExtensions() { | 4169 MaybeObject* JSObject::PreventExtensions() { |
| 4070 Isolate* isolate = GetIsolate(); | 4170 Isolate* isolate = GetIsolate(); |
| 4071 if (IsAccessCheckNeeded() && | 4171 if (IsAccessCheckNeeded() && |
| 4072 !isolate->MayNamedAccess(this, | 4172 !isolate->MayNamedAccess(this, |
| 4073 isolate->heap()->undefined_value(), | 4173 isolate->heap()->undefined_value(), |
| 4074 v8::ACCESS_KEYS)) { | 4174 v8::ACCESS_KEYS)) { |
| 4075 isolate->ReportFailedAccessCheck(this, v8::ACCESS_KEYS); | 4175 isolate->ReportFailedAccessCheck(this, v8::ACCESS_KEYS); |
| 4076 return isolate->heap()->false_value(); | 4176 return isolate->heap()->false_value(); |
| 4077 } | 4177 } |
| 4078 | 4178 |
| 4079 if (IsJSGlobalProxy()) { | 4179 if (IsJSGlobalProxy()) { |
| 4080 Object* proto = GetPrototype(); | 4180 Object* proto = GetPrototype(); |
| 4081 if (proto->IsNull()) return this; | 4181 if (proto->IsNull()) return this; |
| 4082 ASSERT(proto->IsJSGlobalObject()); | 4182 ASSERT(proto->IsJSGlobalObject()); |
| 4083 return JSObject::cast(proto)->PreventExtensions(); | 4183 return JSObject::cast(proto)->PreventExtensions(); |
| 4084 } | 4184 } |
| 4085 | 4185 |
| 4086 // It's not possible to seal objects with external array elements | 4186 // It's not possible to seal objects with external array elements |
| 4087 if (HasExternalArrayElements()) { | 4187 if (HasExternalArrayElements()) { |
| 4088 HandleScope scope(isolate); | 4188 HandleScope scope(isolate); |
| 4089 Handle<Object> object(this); | 4189 Handle<Object> object(this); |
| 4090 Handle<Object> error = | 4190 Handle<Object> error = |
| 4091 isolate->factory()->NewTypeError( | 4191 isolate->factory()->NewTypeError( |
| 4092 "cant_prevent_ext_external_array_elements", | 4192 "cant_prevent_ext_external_array_elements", |
| 4093 HandleVector(&object, 1)); | 4193 HandleVector(&object, 1)); |
| 4094 return isolate->Throw(*error); | 4194 return isolate->Throw(*error); |
| 4095 } | 4195 } |
| 4096 | 4196 |
| 4097 // If there are fast elements we normalize. | 4197 // If there are fast elements we normalize. |
| 4098 NumberDictionary* dictionary = NULL; | 4198 SeededNumberDictionary* dictionary = NULL; |
| 4099 { MaybeObject* maybe = NormalizeElements(); | 4199 { MaybeObject* maybe = NormalizeElements(); |
| 4100 if (!maybe->To<NumberDictionary>(&dictionary)) return maybe; | 4200 if (!maybe->To<SeededNumberDictionary>(&dictionary)) return maybe; |
| 4101 } | 4201 } |
| 4102 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 4202 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
| 4103 // Make sure that we never go back to fast case. | 4203 // Make sure that we never go back to fast case. |
| 4104 dictionary->set_requires_slow_elements(); | 4204 dictionary->set_requires_slow_elements(); |
| 4105 | 4205 |
| 4106 // Do a map transition, other objects with this map may still | 4206 // Do a map transition, other objects with this map may still |
| 4107 // be extensible. | 4207 // be extensible. |
| 4108 Map* new_map; | 4208 Map* new_map; |
| 4109 { MaybeObject* maybe = map()->CopyDropTransitions(); | 4209 { MaybeObject* maybe = map()->CopyDropTransitions(); |
| 4110 if (!maybe->To<Map>(&new_map)) return maybe; | 4210 if (!maybe->To<Map>(&new_map)) return maybe; |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4250 current != heap->null_value() && current->IsJSObject(); | 4350 current != heap->null_value() && current->IsJSObject(); |
| 4251 current = JSObject::cast(current)->GetPrototype()) { | 4351 current = JSObject::cast(current)->GetPrototype()) { |
| 4252 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); | 4352 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); |
| 4253 if (result->IsProperty() && result->type() == CALLBACKS) return; | 4353 if (result->IsProperty() && result->type() == CALLBACKS) return; |
| 4254 } | 4354 } |
| 4255 result->NotFound(); | 4355 result->NotFound(); |
| 4256 } | 4356 } |
| 4257 | 4357 |
| 4258 | 4358 |
| 4259 // Search for a getter or setter in an elements dictionary and update its | 4359 // Search for a getter or setter in an elements dictionary and update its |
| 4260 // attributes. Returns either undefined if the element is non-deletable, or | 4360 // attributes. Returns either undefined if the element is non-deletable, or the |
| 4261 // the getter/setter pair (fixed array) if there is an existing one, or the | 4361 // getter/setter pair if there is an existing one, or the hole value if the |
| 4262 // hole value if the element does not exist or is a normal non-getter/setter | 4362 // element does not exist or is a normal non-getter/setter data element. |
| 4263 // data element. | 4363 static Object* UpdateGetterSetterInDictionary( |
| 4264 static Object* UpdateGetterSetterInDictionary(NumberDictionary* dictionary, | 4364 SeededNumberDictionary* dictionary, |
| 4265 uint32_t index, | 4365 uint32_t index, |
| 4266 PropertyAttributes attributes, | 4366 PropertyAttributes attributes, |
| 4267 Heap* heap) { | 4367 Heap* heap) { |
| 4268 int entry = dictionary->FindEntry(index); | 4368 int entry = dictionary->FindEntry(index); |
| 4269 if (entry != NumberDictionary::kNotFound) { | 4369 if (entry != SeededNumberDictionary::kNotFound) { |
| 4270 Object* result = dictionary->ValueAt(entry); | 4370 Object* result = dictionary->ValueAt(entry); |
| 4271 PropertyDetails details = dictionary->DetailsAt(entry); | 4371 PropertyDetails details = dictionary->DetailsAt(entry); |
| 4272 // TODO(mstarzinger): We should check for details.IsDontDelete() here once | 4372 // TODO(mstarzinger): We should check for details.IsDontDelete() here once |
| 4273 // we only call into the runtime once to set both getter and setter. | 4373 // we only call into the runtime once to set both getter and setter. |
| 4274 if (details.type() == CALLBACKS && result->IsFixedArray()) { | 4374 if (details.type() == CALLBACKS && result->IsAccessorPair()) { |
| 4275 if (details.attributes() != attributes) { | 4375 if (details.attributes() != attributes) { |
| 4276 dictionary->DetailsAtPut(entry, | 4376 dictionary->DetailsAtPut(entry, |
| 4277 PropertyDetails(attributes, CALLBACKS, index)); | 4377 PropertyDetails(attributes, CALLBACKS, index)); |
| 4278 } | 4378 } |
| 4279 return result; | 4379 return result; |
| 4280 } | 4380 } |
| 4281 } | 4381 } |
| 4282 return heap->the_hole_value(); | 4382 return heap->the_hole_value(); |
| 4283 } | 4383 } |
| 4284 | 4384 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4331 // Ascertain whether we have read-only properties or an existing | 4431 // Ascertain whether we have read-only properties or an existing |
| 4332 // getter/setter pair in an arguments elements dictionary backing | 4432 // getter/setter pair in an arguments elements dictionary backing |
| 4333 // store. | 4433 // store. |
| 4334 FixedArray* parameter_map = FixedArray::cast(elements()); | 4434 FixedArray* parameter_map = FixedArray::cast(elements()); |
| 4335 uint32_t length = parameter_map->length(); | 4435 uint32_t length = parameter_map->length(); |
| 4336 Object* probe = | 4436 Object* probe = |
| 4337 index < (length - 2) ? parameter_map->get(index + 2) : NULL; | 4437 index < (length - 2) ? parameter_map->get(index + 2) : NULL; |
| 4338 if (probe == NULL || probe->IsTheHole()) { | 4438 if (probe == NULL || probe->IsTheHole()) { |
| 4339 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 4439 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 4340 if (arguments->IsDictionary()) { | 4440 if (arguments->IsDictionary()) { |
| 4341 NumberDictionary* dictionary = NumberDictionary::cast(arguments); | 4441 SeededNumberDictionary* dictionary = |
| 4442 SeededNumberDictionary::cast(arguments); |
| 4342 probe = UpdateGetterSetterInDictionary(dictionary, | 4443 probe = UpdateGetterSetterInDictionary(dictionary, |
| 4343 index, | 4444 index, |
| 4344 attributes, | 4445 attributes, |
| 4345 heap); | 4446 heap); |
| 4346 if (!probe->IsTheHole()) return probe; | 4447 if (!probe->IsTheHole()) return probe; |
| 4347 } | 4448 } |
| 4348 } | 4449 } |
| 4349 break; | 4450 break; |
| 4350 } | 4451 } |
| 4351 } | 4452 } |
| 4352 } else { | 4453 } else { |
| 4353 // Lookup the name. | 4454 // Lookup the name. |
| 4354 LookupResult result(heap->isolate()); | 4455 LookupResult result(heap->isolate()); |
| 4355 LocalLookupRealNamedProperty(name, &result); | 4456 LocalLookupRealNamedProperty(name, &result); |
| 4356 if (result.IsProperty()) { | 4457 if (result.IsProperty()) { |
| 4357 // TODO(mstarzinger): We should check for result.IsDontDelete() here once | 4458 // TODO(mstarzinger): We should check for result.IsDontDelete() here once |
| 4358 // we only call into the runtime once to set both getter and setter. | 4459 // we only call into the runtime once to set both getter and setter. |
| 4359 if (result.type() == CALLBACKS) { | 4460 if (result.type() == CALLBACKS) { |
| 4360 Object* obj = result.GetCallbackObject(); | 4461 Object* obj = result.GetCallbackObject(); |
| 4361 // Need to preserve old getters/setters. | 4462 // Need to preserve old getters/setters. |
| 4362 if (obj->IsFixedArray()) { | 4463 if (obj->IsAccessorPair()) { |
| 4363 // Use set to update attributes. | 4464 // Use set to update attributes. |
| 4364 return SetPropertyCallback(name, obj, attributes); | 4465 return SetPropertyCallback(name, obj, attributes); |
| 4365 } | 4466 } |
| 4366 } | 4467 } |
| 4367 } | 4468 } |
| 4368 } | 4469 } |
| 4369 | 4470 |
| 4370 // Allocate the fixed array to hold getter and setter. | 4471 AccessorPair* accessors; |
| 4371 Object* structure; | 4472 { MaybeObject* maybe_accessors = heap->AllocateAccessorPair(); |
| 4372 { MaybeObject* maybe_structure = heap->AllocateFixedArray(2, TENURED); | 4473 if (!maybe_accessors->To<AccessorPair>(&accessors)) return maybe_accessors; |
| 4373 if (!maybe_structure->ToObject(&structure)) return maybe_structure; | |
| 4374 } | 4474 } |
| 4375 | 4475 |
| 4376 if (is_element) { | 4476 if (is_element) { |
| 4377 return SetElementCallback(index, structure, attributes); | 4477 return SetElementCallback(index, accessors, attributes); |
| 4378 } else { | 4478 } else { |
| 4379 return SetPropertyCallback(name, structure, attributes); | 4479 return SetPropertyCallback(name, accessors, attributes); |
| 4380 } | 4480 } |
| 4381 } | 4481 } |
| 4382 | 4482 |
| 4383 | 4483 |
| 4384 bool JSObject::CanSetCallback(String* name) { | 4484 bool JSObject::CanSetCallback(String* name) { |
| 4385 ASSERT(!IsAccessCheckNeeded() || | 4485 ASSERT(!IsAccessCheckNeeded() || |
| 4386 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); | 4486 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); |
| 4387 | 4487 |
| 4388 // Check if there is an API defined callback object which prohibits | 4488 // Check if there is an API defined callback object which prohibits |
| 4389 // callback overwriting in this object or it's prototype chain. | 4489 // callback overwriting in this object or it's prototype chain. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4404 return true; | 4504 return true; |
| 4405 } | 4505 } |
| 4406 | 4506 |
| 4407 | 4507 |
| 4408 MaybeObject* JSObject::SetElementCallback(uint32_t index, | 4508 MaybeObject* JSObject::SetElementCallback(uint32_t index, |
| 4409 Object* structure, | 4509 Object* structure, |
| 4410 PropertyAttributes attributes) { | 4510 PropertyAttributes attributes) { |
| 4411 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); | 4511 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); |
| 4412 | 4512 |
| 4413 // Normalize elements to make this operation simple. | 4513 // Normalize elements to make this operation simple. |
| 4414 NumberDictionary* dictionary = NULL; | 4514 SeededNumberDictionary* dictionary = NULL; |
| 4415 { Object* result; | 4515 { Object* result; |
| 4416 MaybeObject* maybe = NormalizeElements(); | 4516 MaybeObject* maybe = NormalizeElements(); |
| 4417 if (!maybe->ToObject(&result)) return maybe; | 4517 if (!maybe->ToObject(&result)) return maybe; |
| 4418 dictionary = NumberDictionary::cast(result); | 4518 dictionary = SeededNumberDictionary::cast(result); |
| 4419 } | 4519 } |
| 4420 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 4520 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
| 4421 | 4521 |
| 4422 // Update the dictionary with the new CALLBACKS property. | 4522 // Update the dictionary with the new CALLBACKS property. |
| 4423 { Object* result; | 4523 { Object* result; |
| 4424 MaybeObject* maybe = dictionary->Set(index, structure, details); | 4524 MaybeObject* maybe = dictionary->Set(index, structure, details); |
| 4425 if (!maybe->ToObject(&result)) return maybe; | 4525 if (!maybe->ToObject(&result)) return maybe; |
| 4426 dictionary = NumberDictionary::cast(result); | 4526 dictionary = SeededNumberDictionary::cast(result); |
| 4427 } | 4527 } |
| 4428 | 4528 |
| 4429 dictionary->set_requires_slow_elements(); | 4529 dictionary->set_requires_slow_elements(); |
| 4430 // Update the dictionary backing store on the object. | 4530 // Update the dictionary backing store on the object. |
| 4431 if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) { | 4531 if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) { |
| 4432 // Also delete any parameter alias. | 4532 // Also delete any parameter alias. |
| 4433 // | 4533 // |
| 4434 // TODO(kmillikin): when deleting the last parameter alias we could | 4534 // TODO(kmillikin): when deleting the last parameter alias we could |
| 4435 // switch to a direct backing store without the parameter map. This | 4535 // switch to a direct backing store without the parameter map. This |
| 4436 // would allow GC of the context. | 4536 // would allow GC of the context. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4505 } | 4605 } |
| 4506 | 4606 |
| 4507 if (IsJSGlobalProxy()) { | 4607 if (IsJSGlobalProxy()) { |
| 4508 Object* proto = GetPrototype(); | 4608 Object* proto = GetPrototype(); |
| 4509 if (proto->IsNull()) return this; | 4609 if (proto->IsNull()) return this; |
| 4510 ASSERT(proto->IsJSGlobalObject()); | 4610 ASSERT(proto->IsJSGlobalObject()); |
| 4511 return JSObject::cast(proto)->DefineAccessor(name, is_getter, | 4611 return JSObject::cast(proto)->DefineAccessor(name, is_getter, |
| 4512 fun, attributes); | 4612 fun, attributes); |
| 4513 } | 4613 } |
| 4514 | 4614 |
| 4515 Object* array; | 4615 Object* accessors; |
| 4516 { MaybeObject* maybe_array = DefineGetterSetter(name, attributes); | 4616 { MaybeObject* maybe_accessors = DefineGetterSetter(name, attributes); |
| 4517 if (!maybe_array->ToObject(&array)) return maybe_array; | 4617 if (!maybe_accessors->To<Object>(&accessors)) return maybe_accessors; |
| 4518 } | 4618 } |
| 4519 if (array->IsUndefined()) return array; | 4619 if (accessors->IsUndefined()) return accessors; |
| 4520 FixedArray::cast(array)->set(is_getter ? 0 : 1, fun); | 4620 if (is_getter) { |
| 4621 AccessorPair::cast(accessors)->set_getter(fun); |
| 4622 } else { |
| 4623 AccessorPair::cast(accessors)->set_setter(fun); |
| 4624 } |
| 4521 return this; | 4625 return this; |
| 4522 } | 4626 } |
| 4523 | 4627 |
| 4524 | 4628 |
| 4525 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { | 4629 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { |
| 4526 Isolate* isolate = GetIsolate(); | 4630 Isolate* isolate = GetIsolate(); |
| 4527 String* name = String::cast(info->name()); | 4631 String* name = String::cast(info->name()); |
| 4528 // Check access rights if needed. | 4632 // Check access rights if needed. |
| 4529 if (IsAccessCheckNeeded() && | 4633 if (IsAccessCheckNeeded() && |
| 4530 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) { | 4634 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4614 AssertNoContextChange ncc; | 4718 AssertNoContextChange ncc; |
| 4615 | 4719 |
| 4616 // Check access rights if needed. | 4720 // Check access rights if needed. |
| 4617 if (IsAccessCheckNeeded() && | 4721 if (IsAccessCheckNeeded() && |
| 4618 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { | 4722 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { |
| 4619 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 4723 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 4620 return heap->undefined_value(); | 4724 return heap->undefined_value(); |
| 4621 } | 4725 } |
| 4622 | 4726 |
| 4623 // Make the lookup and include prototypes. | 4727 // Make the lookup and include prototypes. |
| 4624 // Introducing constants below makes static constants usage purely static | |
| 4625 // and avoids linker errors in debug build using gcc. | |
| 4626 const int getter_index = kGetterIndex; | |
| 4627 const int setter_index = kSetterIndex; | |
| 4628 int accessor_index = is_getter ? getter_index : setter_index; | |
| 4629 uint32_t index = 0; | 4728 uint32_t index = 0; |
| 4630 if (name->AsArrayIndex(&index)) { | 4729 if (name->AsArrayIndex(&index)) { |
| 4631 for (Object* obj = this; | 4730 for (Object* obj = this; |
| 4632 obj != heap->null_value(); | 4731 obj != heap->null_value(); |
| 4633 obj = JSObject::cast(obj)->GetPrototype()) { | 4732 obj = JSObject::cast(obj)->GetPrototype()) { |
| 4634 JSObject* js_object = JSObject::cast(obj); | 4733 JSObject* js_object = JSObject::cast(obj); |
| 4635 if (js_object->HasDictionaryElements()) { | 4734 if (js_object->HasDictionaryElements()) { |
| 4636 NumberDictionary* dictionary = js_object->element_dictionary(); | 4735 SeededNumberDictionary* dictionary = js_object->element_dictionary(); |
| 4637 int entry = dictionary->FindEntry(index); | 4736 int entry = dictionary->FindEntry(index); |
| 4638 if (entry != NumberDictionary::kNotFound) { | 4737 if (entry != SeededNumberDictionary::kNotFound) { |
| 4639 Object* element = dictionary->ValueAt(entry); | 4738 Object* element = dictionary->ValueAt(entry); |
| 4640 PropertyDetails details = dictionary->DetailsAt(entry); | 4739 PropertyDetails details = dictionary->DetailsAt(entry); |
| 4641 if (details.type() == CALLBACKS) { | 4740 if (details.type() == CALLBACKS) { |
| 4642 if (element->IsFixedArray()) { | 4741 if (element->IsAccessorPair()) { |
| 4643 return FixedArray::cast(element)->get(accessor_index); | 4742 AccessorPair* accessors = AccessorPair::cast(element); |
| 4743 return is_getter ? accessors->getter() : accessors->setter(); |
| 4644 } | 4744 } |
| 4645 } | 4745 } |
| 4646 } | 4746 } |
| 4647 } | 4747 } |
| 4648 } | 4748 } |
| 4649 } else { | 4749 } else { |
| 4650 for (Object* obj = this; | 4750 for (Object* obj = this; |
| 4651 obj != heap->null_value(); | 4751 obj != heap->null_value(); |
| 4652 obj = JSObject::cast(obj)->GetPrototype()) { | 4752 obj = JSObject::cast(obj)->GetPrototype()) { |
| 4653 LookupResult result(heap->isolate()); | 4753 LookupResult result(heap->isolate()); |
| 4654 JSObject::cast(obj)->LocalLookup(name, &result); | 4754 JSObject::cast(obj)->LocalLookup(name, &result); |
| 4655 if (result.IsProperty()) { | 4755 if (result.IsProperty()) { |
| 4656 if (result.IsReadOnly()) return heap->undefined_value(); | 4756 if (result.IsReadOnly()) return heap->undefined_value(); |
| 4657 if (result.type() == CALLBACKS) { | 4757 if (result.type() == CALLBACKS) { |
| 4658 Object* obj = result.GetCallbackObject(); | 4758 Object* obj = result.GetCallbackObject(); |
| 4659 if (obj->IsFixedArray()) { | 4759 if (obj->IsAccessorPair()) { |
| 4660 return FixedArray::cast(obj)->get(accessor_index); | 4760 AccessorPair* accessors = AccessorPair::cast(obj); |
| 4761 return is_getter ? accessors->getter() : accessors->setter(); |
| 4661 } | 4762 } |
| 4662 } | 4763 } |
| 4663 } | 4764 } |
| 4664 } | 4765 } |
| 4665 } | 4766 } |
| 4666 return heap->undefined_value(); | 4767 return heap->undefined_value(); |
| 4667 } | 4768 } |
| 4668 | 4769 |
| 4669 | 4770 |
| 4670 Object* JSObject::SlowReverseLookup(Object* value) { | 4771 Object* JSObject::SlowReverseLookup(Object* value) { |
| (...skipping 2155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6826 // Should only be called if hash code has not yet been computed. | 6927 // Should only be called if hash code has not yet been computed. |
| 6827 ASSERT(!HasHashCode()); | 6928 ASSERT(!HasHashCode()); |
| 6828 | 6929 |
| 6829 const int len = length(); | 6930 const int len = length(); |
| 6830 | 6931 |
| 6831 // Compute the hash code. | 6932 // Compute the hash code. |
| 6832 uint32_t field = 0; | 6933 uint32_t field = 0; |
| 6833 if (StringShape(this).IsSequentialAscii()) { | 6934 if (StringShape(this).IsSequentialAscii()) { |
| 6834 field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), | 6935 field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), |
| 6835 len, | 6936 len, |
| 6836 GetHeap()->StringHashSeed()); | 6937 GetHeap()->HashSeed()); |
| 6837 } else if (StringShape(this).IsSequentialTwoByte()) { | 6938 } else if (StringShape(this).IsSequentialTwoByte()) { |
| 6838 field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(), | 6939 field = HashSequentialString(SeqTwoByteString::cast(this)->GetChars(), |
| 6839 len, | 6940 len, |
| 6840 GetHeap()->StringHashSeed()); | 6941 GetHeap()->HashSeed()); |
| 6841 } else { | 6942 } else { |
| 6842 StringInputBuffer buffer(this); | 6943 StringInputBuffer buffer(this); |
| 6843 field = ComputeHashField(&buffer, len, GetHeap()->StringHashSeed()); | 6944 field = ComputeHashField(&buffer, len, GetHeap()->HashSeed()); |
| 6844 } | 6945 } |
| 6845 | 6946 |
| 6846 // Store the hash code in the object. | 6947 // Store the hash code in the object. |
| 6847 set_hash_field(field); | 6948 set_hash_field(field); |
| 6848 | 6949 |
| 6849 // Check the hash code is there. | 6950 // Check the hash code is there. |
| 6850 ASSERT(HasHashCode()); | 6951 ASSERT(HasHashCode()); |
| 6851 uint32_t result = field >> kHashShift; | 6952 uint32_t result = field >> kHashShift; |
| 6852 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. | 6953 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
| 6853 return result; | 6954 return result; |
| (...skipping 1310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8164 reinterpret_cast<void*>(from), | 8265 reinterpret_cast<void*>(from), |
| 8165 kPointerSize * copy_size); | 8266 kPointerSize * copy_size); |
| 8166 } else { | 8267 } else { |
| 8167 for (int i = 0; i < copy_size; ++i) { | 8268 for (int i = 0; i < copy_size; ++i) { |
| 8168 destination->set(i, source->get(i), mode); | 8269 destination->set(i, source->get(i), mode); |
| 8169 } | 8270 } |
| 8170 } | 8271 } |
| 8171 } | 8272 } |
| 8172 | 8273 |
| 8173 | 8274 |
| 8174 static void CopySlowElementsToFast(NumberDictionary* source, | 8275 static void CopySlowElementsToFast(SeededNumberDictionary* source, |
| 8175 FixedArray* destination, | 8276 FixedArray* destination, |
| 8176 WriteBarrierMode mode) { | 8277 WriteBarrierMode mode) { |
| 8177 int destination_length = destination->length(); | 8278 int destination_length = destination->length(); |
| 8178 for (int i = 0; i < source->Capacity(); ++i) { | 8279 for (int i = 0; i < source->Capacity(); ++i) { |
| 8179 Object* key = source->KeyAt(i); | 8280 Object* key = source->KeyAt(i); |
| 8180 if (key->IsNumber()) { | 8281 if (key->IsNumber()) { |
| 8181 uint32_t entry = static_cast<uint32_t>(key->Number()); | 8282 uint32_t entry = static_cast<uint32_t>(key->Number()); |
| 8182 if (entry < static_cast<uint32_t>(destination_length)) { | 8283 if (entry < static_cast<uint32_t>(destination_length)) { |
| 8183 destination->set(entry, source->ValueAt(i), mode); | 8284 destination->set(entry, source->ValueAt(i), mode); |
| 8184 } | 8285 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8230 AssertNoAllocation no_gc; | 8331 AssertNoAllocation no_gc; |
| 8231 WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc)); | 8332 WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc)); |
| 8232 CopyFastElementsToFast(FixedArray::cast(old_elements_raw), | 8333 CopyFastElementsToFast(FixedArray::cast(old_elements_raw), |
| 8233 new_elements, mode); | 8334 new_elements, mode); |
| 8234 set_map_and_elements(new_map, new_elements); | 8335 set_map_and_elements(new_map, new_elements); |
| 8235 break; | 8336 break; |
| 8236 } | 8337 } |
| 8237 case DICTIONARY_ELEMENTS: { | 8338 case DICTIONARY_ELEMENTS: { |
| 8238 AssertNoAllocation no_gc; | 8339 AssertNoAllocation no_gc; |
| 8239 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); | 8340 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); |
| 8240 CopySlowElementsToFast(NumberDictionary::cast(old_elements_raw), | 8341 CopySlowElementsToFast(SeededNumberDictionary::cast(old_elements_raw), |
| 8241 new_elements, | 8342 new_elements, |
| 8242 mode); | 8343 mode); |
| 8243 set_map_and_elements(new_map, new_elements); | 8344 set_map_and_elements(new_map, new_elements); |
| 8244 break; | 8345 break; |
| 8245 } | 8346 } |
| 8246 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 8347 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 8247 AssertNoAllocation no_gc; | 8348 AssertNoAllocation no_gc; |
| 8248 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); | 8349 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); |
| 8249 // The object's map and the parameter map are unchanged, the unaliased | 8350 // The object's map and the parameter map are unchanged, the unaliased |
| 8250 // arguments are copied to the new backing store. | 8351 // arguments are copied to the new backing store. |
| 8251 FixedArray* parameter_map = FixedArray::cast(old_elements_raw); | 8352 FixedArray* parameter_map = FixedArray::cast(old_elements_raw); |
| 8252 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 8353 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 8253 if (arguments->IsDictionary()) { | 8354 if (arguments->IsDictionary()) { |
| 8254 CopySlowElementsToFast(NumberDictionary::cast(arguments), | 8355 CopySlowElementsToFast(SeededNumberDictionary::cast(arguments), |
| 8255 new_elements, | 8356 new_elements, |
| 8256 mode); | 8357 mode); |
| 8257 } else { | 8358 } else { |
| 8258 CopyFastElementsToFast(arguments, new_elements, mode); | 8359 CopyFastElementsToFast(arguments, new_elements, mode); |
| 8259 } | 8360 } |
| 8260 parameter_map->set(1, new_elements); | 8361 parameter_map->set(1, new_elements); |
| 8261 break; | 8362 break; |
| 8262 } | 8363 } |
| 8263 case FAST_DOUBLE_ELEMENTS: { | 8364 case FAST_DOUBLE_ELEMENTS: { |
| 8264 FixedDoubleArray* old_elements = FixedDoubleArray::cast(old_elements_raw); | 8365 FixedDoubleArray* old_elements = FixedDoubleArray::cast(old_elements_raw); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8340 case FAST_SMI_ONLY_ELEMENTS: | 8441 case FAST_SMI_ONLY_ELEMENTS: |
| 8341 case FAST_ELEMENTS: { | 8442 case FAST_ELEMENTS: { |
| 8342 elems->Initialize(FixedArray::cast(old_elements)); | 8443 elems->Initialize(FixedArray::cast(old_elements)); |
| 8343 break; | 8444 break; |
| 8344 } | 8445 } |
| 8345 case FAST_DOUBLE_ELEMENTS: { | 8446 case FAST_DOUBLE_ELEMENTS: { |
| 8346 elems->Initialize(FixedDoubleArray::cast(old_elements)); | 8447 elems->Initialize(FixedDoubleArray::cast(old_elements)); |
| 8347 break; | 8448 break; |
| 8348 } | 8449 } |
| 8349 case DICTIONARY_ELEMENTS: { | 8450 case DICTIONARY_ELEMENTS: { |
| 8350 elems->Initialize(NumberDictionary::cast(old_elements)); | 8451 elems->Initialize(SeededNumberDictionary::cast(old_elements)); |
| 8351 break; | 8452 break; |
| 8352 } | 8453 } |
| 8353 default: | 8454 default: |
| 8354 UNREACHABLE(); | 8455 UNREACHABLE(); |
| 8355 break; | 8456 break; |
| 8356 } | 8457 } |
| 8357 | 8458 |
| 8358 if (FLAG_trace_elements_transitions) { | 8459 if (FLAG_trace_elements_transitions) { |
| 8359 PrintElementsTransition(stdout, elements_kind, old_elements, | 8460 PrintElementsTransition(stdout, elements_kind, old_elements, |
| 8360 FAST_DOUBLE_ELEMENTS, elems); | 8461 FAST_DOUBLE_ELEMENTS, elems); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8600 case EXTERNAL_FLOAT_ELEMENTS: | 8701 case EXTERNAL_FLOAT_ELEMENTS: |
| 8601 case EXTERNAL_DOUBLE_ELEMENTS: { | 8702 case EXTERNAL_DOUBLE_ELEMENTS: { |
| 8602 ExternalArray* array = ExternalArray::cast(elements()); | 8703 ExternalArray* array = ExternalArray::cast(elements()); |
| 8603 if (index < static_cast<uint32_t>(array->length())) { | 8704 if (index < static_cast<uint32_t>(array->length())) { |
| 8604 return true; | 8705 return true; |
| 8605 } | 8706 } |
| 8606 break; | 8707 break; |
| 8607 } | 8708 } |
| 8608 case DICTIONARY_ELEMENTS: { | 8709 case DICTIONARY_ELEMENTS: { |
| 8609 if (element_dictionary()->FindEntry(index) | 8710 if (element_dictionary()->FindEntry(index) |
| 8610 != NumberDictionary::kNotFound) { | 8711 != SeededNumberDictionary::kNotFound) { |
| 8611 return true; | 8712 return true; |
| 8612 } | 8713 } |
| 8613 break; | 8714 break; |
| 8614 } | 8715 } |
| 8615 case NON_STRICT_ARGUMENTS_ELEMENTS: | 8716 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 8616 UNREACHABLE(); | 8717 UNREACHABLE(); |
| 8617 break; | 8718 break; |
| 8618 } | 8719 } |
| 8619 | 8720 |
| 8620 // Handle [] on String objects. | 8721 // Handle [] on String objects. |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8738 case EXTERNAL_INT_ELEMENTS: | 8839 case EXTERNAL_INT_ELEMENTS: |
| 8739 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 8840 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 8740 case EXTERNAL_FLOAT_ELEMENTS: | 8841 case EXTERNAL_FLOAT_ELEMENTS: |
| 8741 case EXTERNAL_DOUBLE_ELEMENTS: { | 8842 case EXTERNAL_DOUBLE_ELEMENTS: { |
| 8742 ExternalArray* array = ExternalArray::cast(elements()); | 8843 ExternalArray* array = ExternalArray::cast(elements()); |
| 8743 if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT; | 8844 if (index < static_cast<uint32_t>(array->length())) return FAST_ELEMENT; |
| 8744 break; | 8845 break; |
| 8745 } | 8846 } |
| 8746 case DICTIONARY_ELEMENTS: { | 8847 case DICTIONARY_ELEMENTS: { |
| 8747 if (element_dictionary()->FindEntry(index) != | 8848 if (element_dictionary()->FindEntry(index) != |
| 8748 NumberDictionary::kNotFound) { | 8849 SeededNumberDictionary::kNotFound) { |
| 8749 return DICTIONARY_ELEMENT; | 8850 return DICTIONARY_ELEMENT; |
| 8750 } | 8851 } |
| 8751 break; | 8852 break; |
| 8752 } | 8853 } |
| 8753 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 8854 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 8754 // Aliased parameters and non-aliased elements in a fast backing store | 8855 // Aliased parameters and non-aliased elements in a fast backing store |
| 8755 // behave as FAST_ELEMENT. Non-aliased elements in a dictionary | 8856 // behave as FAST_ELEMENT. Non-aliased elements in a dictionary |
| 8756 // backing store behave as DICTIONARY_ELEMENT. | 8857 // backing store behave as DICTIONARY_ELEMENT. |
| 8757 FixedArray* parameter_map = FixedArray::cast(elements()); | 8858 FixedArray* parameter_map = FixedArray::cast(elements()); |
| 8758 uint32_t length = parameter_map->length(); | 8859 uint32_t length = parameter_map->length(); |
| 8759 Object* probe = | 8860 Object* probe = |
| 8760 index < (length - 2) ? parameter_map->get(index + 2) : NULL; | 8861 index < (length - 2) ? parameter_map->get(index + 2) : NULL; |
| 8761 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT; | 8862 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT; |
| 8762 // If not aliased, check the arguments. | 8863 // If not aliased, check the arguments. |
| 8763 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 8864 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 8764 if (arguments->IsDictionary()) { | 8865 if (arguments->IsDictionary()) { |
| 8765 NumberDictionary* dictionary = NumberDictionary::cast(arguments); | 8866 SeededNumberDictionary* dictionary = |
| 8766 if (dictionary->FindEntry(index) != NumberDictionary::kNotFound) { | 8867 SeededNumberDictionary::cast(arguments); |
| 8868 if (dictionary->FindEntry(index) != SeededNumberDictionary::kNotFound) { |
| 8767 return DICTIONARY_ELEMENT; | 8869 return DICTIONARY_ELEMENT; |
| 8768 } | 8870 } |
| 8769 } else { | 8871 } else { |
| 8770 length = arguments->length(); | 8872 length = arguments->length(); |
| 8771 probe = (index < length) ? arguments->get(index) : NULL; | 8873 probe = (index < length) ? arguments->get(index) : NULL; |
| 8772 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT; | 8874 if (probe != NULL && !probe->IsTheHole()) return FAST_ELEMENT; |
| 8773 } | 8875 } |
| 8774 break; | 8876 break; |
| 8775 } | 8877 } |
| 8776 } | 8878 } |
| 8777 | 8879 |
| 8778 return UNDEFINED_ELEMENT; | 8880 return UNDEFINED_ELEMENT; |
| 8779 } | 8881 } |
| 8780 | 8882 |
| 8781 | 8883 |
| 8782 bool JSObject::HasElementInElements(FixedArray* elements, | 8884 bool JSObject::HasElementInElements(FixedArray* elements, |
| 8783 ElementsKind kind, | 8885 ElementsKind kind, |
| 8784 uint32_t index) { | 8886 uint32_t index) { |
| 8785 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS); | 8887 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS); |
| 8786 if (kind == FAST_ELEMENTS) { | 8888 if (kind == FAST_ELEMENTS) { |
| 8787 int length = IsJSArray() | 8889 int length = IsJSArray() |
| 8788 ? Smi::cast(JSArray::cast(this)->length())->value() | 8890 ? Smi::cast(JSArray::cast(this)->length())->value() |
| 8789 : elements->length(); | 8891 : elements->length(); |
| 8790 if (index < static_cast<uint32_t>(length) && | 8892 if (index < static_cast<uint32_t>(length) && |
| 8791 !elements->get(index)->IsTheHole()) { | 8893 !elements->get(index)->IsTheHole()) { |
| 8792 return true; | 8894 return true; |
| 8793 } | 8895 } |
| 8794 } else { | 8896 } else { |
| 8795 if (NumberDictionary::cast(elements)->FindEntry(index) != | 8897 if (SeededNumberDictionary::cast(elements)->FindEntry(index) != |
| 8796 NumberDictionary::kNotFound) { | 8898 SeededNumberDictionary::kNotFound) { |
| 8797 return true; | 8899 return true; |
| 8798 } | 8900 } |
| 8799 } | 8901 } |
| 8800 return false; | 8902 return false; |
| 8801 } | 8903 } |
| 8802 | 8904 |
| 8803 | 8905 |
| 8804 bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) { | 8906 bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) { |
| 8805 // Check access rights if needed. | 8907 // Check access rights if needed. |
| 8806 if (IsAccessCheckNeeded()) { | 8908 if (IsAccessCheckNeeded()) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8853 case EXTERNAL_FLOAT_ELEMENTS: | 8955 case EXTERNAL_FLOAT_ELEMENTS: |
| 8854 case EXTERNAL_DOUBLE_ELEMENTS: { | 8956 case EXTERNAL_DOUBLE_ELEMENTS: { |
| 8855 ExternalArray* array = ExternalArray::cast(elements()); | 8957 ExternalArray* array = ExternalArray::cast(elements()); |
| 8856 if (index < static_cast<uint32_t>(array->length())) { | 8958 if (index < static_cast<uint32_t>(array->length())) { |
| 8857 return true; | 8959 return true; |
| 8858 } | 8960 } |
| 8859 break; | 8961 break; |
| 8860 } | 8962 } |
| 8861 case DICTIONARY_ELEMENTS: { | 8963 case DICTIONARY_ELEMENTS: { |
| 8862 if (element_dictionary()->FindEntry(index) | 8964 if (element_dictionary()->FindEntry(index) |
| 8863 != NumberDictionary::kNotFound) { | 8965 != SeededNumberDictionary::kNotFound) { |
| 8864 return true; | 8966 return true; |
| 8865 } | 8967 } |
| 8866 break; | 8968 break; |
| 8867 } | 8969 } |
| 8868 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 8970 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 8869 FixedArray* parameter_map = FixedArray::cast(elements()); | 8971 FixedArray* parameter_map = FixedArray::cast(elements()); |
| 8870 uint32_t length = parameter_map->length(); | 8972 uint32_t length = parameter_map->length(); |
| 8871 Object* probe = | 8973 Object* probe = |
| 8872 (index < length - 2) ? parameter_map->get(index + 2) : NULL; | 8974 (index < length - 2) ? parameter_map->get(index + 2) : NULL; |
| 8873 if (probe != NULL && !probe->IsTheHole()) return true; | 8975 if (probe != NULL && !probe->IsTheHole()) return true; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8957 // Leaving JavaScript. | 9059 // Leaving JavaScript. |
| 8958 VMState state(isolate, EXTERNAL); | 9060 VMState state(isolate, EXTERNAL); |
| 8959 result = call_fun(v8::Utils::ToLocal(key), info); | 9061 result = call_fun(v8::Utils::ToLocal(key), info); |
| 8960 } | 9062 } |
| 8961 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 9063 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 8962 if (result.IsEmpty()) return isolate->heap()->undefined_value(); | 9064 if (result.IsEmpty()) return isolate->heap()->undefined_value(); |
| 8963 return *v8::Utils::OpenHandle(*result); | 9065 return *v8::Utils::OpenHandle(*result); |
| 8964 } | 9066 } |
| 8965 | 9067 |
| 8966 // __defineGetter__ callback | 9068 // __defineGetter__ callback |
| 8967 if (structure->IsFixedArray()) { | 9069 if (structure->IsAccessorPair()) { |
| 8968 Object* getter = FixedArray::cast(structure)->get(kGetterIndex); | 9070 Object* getter = AccessorPair::cast(structure)->getter(); |
| 8969 if (getter->IsSpecFunction()) { | 9071 if (getter->IsSpecFunction()) { |
| 8970 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 9072 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 8971 return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter)); | 9073 return GetPropertyWithDefinedGetter(receiver, JSReceiver::cast(getter)); |
| 8972 } | 9074 } |
| 8973 // Getter is not a function. | 9075 // Getter is not a function. |
| 8974 return isolate->heap()->undefined_value(); | 9076 return isolate->heap()->undefined_value(); |
| 8975 } | 9077 } |
| 8976 | 9078 |
| 8977 UNREACHABLE(); | 9079 UNREACHABLE(); |
| 8978 return NULL; | 9080 return NULL; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9014 // Leaving JavaScript. | 9116 // Leaving JavaScript. |
| 9015 VMState state(isolate, EXTERNAL); | 9117 VMState state(isolate, EXTERNAL); |
| 9016 call_fun(v8::Utils::ToLocal(key), | 9118 call_fun(v8::Utils::ToLocal(key), |
| 9017 v8::Utils::ToLocal(value_handle), | 9119 v8::Utils::ToLocal(value_handle), |
| 9018 info); | 9120 info); |
| 9019 } | 9121 } |
| 9020 RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 9122 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
| 9021 return *value_handle; | 9123 return *value_handle; |
| 9022 } | 9124 } |
| 9023 | 9125 |
| 9024 if (structure->IsFixedArray()) { | 9126 if (structure->IsAccessorPair()) { |
| 9025 Handle<Object> setter(FixedArray::cast(structure)->get(kSetterIndex)); | 9127 Handle<Object> setter(AccessorPair::cast(structure)->setter()); |
| 9026 if (setter->IsSpecFunction()) { | 9128 if (setter->IsSpecFunction()) { |
| 9027 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 9129 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 9028 return SetPropertyWithDefinedSetter(JSReceiver::cast(*setter), value); | 9130 return SetPropertyWithDefinedSetter(JSReceiver::cast(*setter), value); |
| 9029 } else { | 9131 } else { |
| 9030 if (strict_mode == kNonStrictMode) { | 9132 if (strict_mode == kNonStrictMode) { |
| 9031 return value; | 9133 return value; |
| 9032 } | 9134 } |
| 9033 Handle<Object> holder_handle(holder, isolate); | 9135 Handle<Object> holder_handle(holder, isolate); |
| 9034 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); | 9136 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); |
| 9035 Handle<Object> args[2] = { key, holder_handle }; | 9137 Handle<Object> args[2] = { key, holder_handle }; |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9176 StrictModeFlag strict_mode, | 9278 StrictModeFlag strict_mode, |
| 9177 bool check_prototype) { | 9279 bool check_prototype) { |
| 9178 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 9280 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
| 9179 Isolate* isolate = GetIsolate(); | 9281 Isolate* isolate = GetIsolate(); |
| 9180 Heap* heap = isolate->heap(); | 9282 Heap* heap = isolate->heap(); |
| 9181 | 9283 |
| 9182 // Insert element in the dictionary. | 9284 // Insert element in the dictionary. |
| 9183 FixedArray* elements = FixedArray::cast(this->elements()); | 9285 FixedArray* elements = FixedArray::cast(this->elements()); |
| 9184 bool is_arguments = | 9286 bool is_arguments = |
| 9185 (elements->map() == heap->non_strict_arguments_elements_map()); | 9287 (elements->map() == heap->non_strict_arguments_elements_map()); |
| 9186 NumberDictionary* dictionary = NULL; | 9288 SeededNumberDictionary* dictionary = NULL; |
| 9187 if (is_arguments) { | 9289 if (is_arguments) { |
| 9188 dictionary = NumberDictionary::cast(elements->get(1)); | 9290 dictionary = SeededNumberDictionary::cast(elements->get(1)); |
| 9189 } else { | 9291 } else { |
| 9190 dictionary = NumberDictionary::cast(elements); | 9292 dictionary = SeededNumberDictionary::cast(elements); |
| 9191 } | 9293 } |
| 9192 | 9294 |
| 9193 int entry = dictionary->FindEntry(index); | 9295 int entry = dictionary->FindEntry(index); |
| 9194 if (entry != NumberDictionary::kNotFound) { | 9296 if (entry != SeededNumberDictionary::kNotFound) { |
| 9195 Object* element = dictionary->ValueAt(entry); | 9297 Object* element = dictionary->ValueAt(entry); |
| 9196 PropertyDetails details = dictionary->DetailsAt(entry); | 9298 PropertyDetails details = dictionary->DetailsAt(entry); |
| 9197 if (details.type() == CALLBACKS) { | 9299 if (details.type() == CALLBACKS) { |
| 9198 return SetElementWithCallback(element, index, value, this, strict_mode); | 9300 return SetElementWithCallback(element, index, value, this, strict_mode); |
| 9199 } else { | 9301 } else { |
| 9200 dictionary->UpdateMaxNumberKey(index); | 9302 dictionary->UpdateMaxNumberKey(index); |
| 9201 // If put fails in strict mode, throw an exception. | 9303 // If put fails in strict mode, throw an exception. |
| 9202 if (!dictionary->ValueAtPut(entry, value) && strict_mode == kStrictMode) { | 9304 if (!dictionary->ValueAtPut(entry, value) && strict_mode == kStrictMode) { |
| 9203 Handle<Object> holder(this); | 9305 Handle<Object> holder(this); |
| 9204 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 9306 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 9229 Handle<Object> args[1] = { name }; | 9331 Handle<Object> args[1] = { name }; |
| 9230 Handle<Object> error = | 9332 Handle<Object> error = |
| 9231 isolate->factory()->NewTypeError("object_not_extensible", | 9333 isolate->factory()->NewTypeError("object_not_extensible", |
| 9232 HandleVector(args, 1)); | 9334 HandleVector(args, 1)); |
| 9233 return isolate->Throw(*error); | 9335 return isolate->Throw(*error); |
| 9234 } | 9336 } |
| 9235 } | 9337 } |
| 9236 FixedArrayBase* new_dictionary; | 9338 FixedArrayBase* new_dictionary; |
| 9237 MaybeObject* maybe = dictionary->AtNumberPut(index, value); | 9339 MaybeObject* maybe = dictionary->AtNumberPut(index, value); |
| 9238 if (!maybe->To<FixedArrayBase>(&new_dictionary)) return maybe; | 9340 if (!maybe->To<FixedArrayBase>(&new_dictionary)) return maybe; |
| 9239 if (dictionary != NumberDictionary::cast(new_dictionary)) { | 9341 if (dictionary != SeededNumberDictionary::cast(new_dictionary)) { |
| 9240 if (is_arguments) { | 9342 if (is_arguments) { |
| 9241 elements->set(1, new_dictionary); | 9343 elements->set(1, new_dictionary); |
| 9242 } else { | 9344 } else { |
| 9243 set_elements(new_dictionary); | 9345 set_elements(new_dictionary); |
| 9244 } | 9346 } |
| 9245 dictionary = NumberDictionary::cast(new_dictionary); | 9347 dictionary = SeededNumberDictionary::cast(new_dictionary); |
| 9246 } | 9348 } |
| 9247 } | 9349 } |
| 9248 | 9350 |
| 9249 // Update the array length if this JSObject is an array. | 9351 // Update the array length if this JSObject is an array. |
| 9250 if (IsJSArray()) { | 9352 if (IsJSArray()) { |
| 9251 MaybeObject* result = | 9353 MaybeObject* result = |
| 9252 JSArray::cast(this)->JSArrayUpdateLengthFromIndex(index, value); | 9354 JSArray::cast(this)->JSArrayUpdateLengthFromIndex(index, value); |
| 9253 if (result->IsFailure()) return result; | 9355 if (result->IsFailure()) return result; |
| 9254 } | 9356 } |
| 9255 | 9357 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9381 Object* value, | 9483 Object* value, |
| 9382 StrictModeFlag strict_mode, | 9484 StrictModeFlag strict_mode, |
| 9383 bool check_proto) { | 9485 bool check_proto) { |
| 9384 return IsJSProxy() | 9486 return IsJSProxy() |
| 9385 ? JSProxy::cast(this)->SetElementWithHandler(index, value, strict_mode) | 9487 ? JSProxy::cast(this)->SetElementWithHandler(index, value, strict_mode) |
| 9386 : JSObject::cast(this)->SetElement(index, value, strict_mode, check_proto) | 9488 : JSObject::cast(this)->SetElement(index, value, strict_mode, check_proto) |
| 9387 ; | 9489 ; |
| 9388 } | 9490 } |
| 9389 | 9491 |
| 9390 | 9492 |
| 9493 Handle<Object> JSObject::SetOwnElement(Handle<JSObject> object, |
| 9494 uint32_t index, |
| 9495 Handle<Object> value, |
| 9496 StrictModeFlag strict_mode) { |
| 9497 ASSERT(!object->HasExternalArrayElements()); |
| 9498 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 9499 object->SetElement(index, *value, strict_mode, false), |
| 9500 Object); |
| 9501 } |
| 9502 |
| 9503 |
| 9504 Handle<Object> JSObject::SetElement(Handle<JSObject> object, |
| 9505 uint32_t index, |
| 9506 Handle<Object> value, |
| 9507 StrictModeFlag strict_mode) { |
| 9508 if (object->HasExternalArrayElements()) { |
| 9509 if (!value->IsSmi() && !value->IsHeapNumber() && !value->IsUndefined()) { |
| 9510 bool has_exception; |
| 9511 Handle<Object> number = Execution::ToNumber(value, &has_exception); |
| 9512 if (has_exception) return Handle<Object>(); |
| 9513 value = number; |
| 9514 } |
| 9515 } |
| 9516 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 9517 object->SetElement(index, *value, strict_mode, true), |
| 9518 Object); |
| 9519 } |
| 9520 |
| 9521 |
| 9391 MaybeObject* JSObject::SetElement(uint32_t index, | 9522 MaybeObject* JSObject::SetElement(uint32_t index, |
| 9392 Object* value, | 9523 Object* value, |
| 9393 StrictModeFlag strict_mode, | 9524 StrictModeFlag strict_mode, |
| 9394 bool check_prototype) { | 9525 bool check_prototype) { |
| 9395 // Check access rights if needed. | 9526 // Check access rights if needed. |
| 9396 if (IsAccessCheckNeeded()) { | 9527 if (IsAccessCheckNeeded()) { |
| 9397 Heap* heap = GetHeap(); | 9528 Heap* heap = GetHeap(); |
| 9398 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 9529 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
| 9399 HandleScope scope(heap->isolate()); | 9530 HandleScope scope(heap->isolate()); |
| 9400 Handle<Object> value_handle(value); | 9531 Handle<Object> value_handle(value); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9503 } | 9634 } |
| 9504 } | 9635 } |
| 9505 } | 9636 } |
| 9506 // All possible cases have been handled above. Add a return to avoid the | 9637 // All possible cases have been handled above. Add a return to avoid the |
| 9507 // complaints from the compiler. | 9638 // complaints from the compiler. |
| 9508 UNREACHABLE(); | 9639 UNREACHABLE(); |
| 9509 return isolate->heap()->null_value(); | 9640 return isolate->heap()->null_value(); |
| 9510 } | 9641 } |
| 9511 | 9642 |
| 9512 | 9643 |
| 9644 Handle<Object> JSObject::TransitionElementsKind(Handle<JSObject> object, |
| 9645 ElementsKind to_kind) { |
| 9646 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 9647 object->TransitionElementsKind(to_kind), |
| 9648 Object); |
| 9649 } |
| 9650 |
| 9651 |
| 9513 MUST_USE_RESULT MaybeObject* JSObject::TransitionElementsKind( | 9652 MUST_USE_RESULT MaybeObject* JSObject::TransitionElementsKind( |
| 9514 ElementsKind to_kind) { | 9653 ElementsKind to_kind) { |
| 9515 ElementsKind from_kind = map()->elements_kind(); | 9654 ElementsKind from_kind = map()->elements_kind(); |
| 9516 FixedArrayBase* elms = FixedArrayBase::cast(elements()); | 9655 FixedArrayBase* elms = FixedArrayBase::cast(elements()); |
| 9517 uint32_t capacity = static_cast<uint32_t>(elms->length()); | 9656 uint32_t capacity = static_cast<uint32_t>(elms->length()); |
| 9518 uint32_t length = capacity; | 9657 uint32_t length = capacity; |
| 9519 | 9658 |
| 9520 if (IsJSArray()) { | 9659 if (IsJSArray()) { |
| 9521 Object* raw_length = JSArray::cast(this)->length(); | 9660 Object* raw_length = JSArray::cast(this)->length(); |
| 9522 if (raw_length->IsUndefined()) { | 9661 if (raw_length->IsUndefined()) { |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9646 *used = 0; | 9785 *used = 0; |
| 9647 | 9786 |
| 9648 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements()); | 9787 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements()); |
| 9649 FixedArray* backing_store = NULL; | 9788 FixedArray* backing_store = NULL; |
| 9650 switch (GetElementsKind()) { | 9789 switch (GetElementsKind()) { |
| 9651 case NON_STRICT_ARGUMENTS_ELEMENTS: | 9790 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 9652 backing_store_base = | 9791 backing_store_base = |
| 9653 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); | 9792 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); |
| 9654 backing_store = FixedArray::cast(backing_store_base); | 9793 backing_store = FixedArray::cast(backing_store_base); |
| 9655 if (backing_store->IsDictionary()) { | 9794 if (backing_store->IsDictionary()) { |
| 9656 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); | 9795 SeededNumberDictionary* dictionary = |
| 9796 SeededNumberDictionary::cast(backing_store); |
| 9657 *capacity = dictionary->Capacity(); | 9797 *capacity = dictionary->Capacity(); |
| 9658 *used = dictionary->NumberOfElements(); | 9798 *used = dictionary->NumberOfElements(); |
| 9659 break; | 9799 break; |
| 9660 } | 9800 } |
| 9661 // Fall through. | 9801 // Fall through. |
| 9662 case FAST_SMI_ONLY_ELEMENTS: | 9802 case FAST_SMI_ONLY_ELEMENTS: |
| 9663 case FAST_ELEMENTS: | 9803 case FAST_ELEMENTS: |
| 9664 backing_store = FixedArray::cast(backing_store_base); | 9804 backing_store = FixedArray::cast(backing_store_base); |
| 9665 *capacity = backing_store->length(); | 9805 *capacity = backing_store->length(); |
| 9666 for (int i = 0; i < *capacity; ++i) { | 9806 for (int i = 0; i < *capacity; ++i) { |
| 9667 if (!backing_store->get(i)->IsTheHole()) ++(*used); | 9807 if (!backing_store->get(i)->IsTheHole()) ++(*used); |
| 9668 } | 9808 } |
| 9669 break; | 9809 break; |
| 9670 case DICTIONARY_ELEMENTS: { | 9810 case DICTIONARY_ELEMENTS: { |
| 9671 NumberDictionary* dictionary = | 9811 SeededNumberDictionary* dictionary = |
| 9672 NumberDictionary::cast(FixedArray::cast(elements())); | 9812 SeededNumberDictionary::cast(FixedArray::cast(elements())); |
| 9673 *capacity = dictionary->Capacity(); | 9813 *capacity = dictionary->Capacity(); |
| 9674 *used = dictionary->NumberOfElements(); | 9814 *used = dictionary->NumberOfElements(); |
| 9675 break; | 9815 break; |
| 9676 } | 9816 } |
| 9677 case FAST_DOUBLE_ELEMENTS: { | 9817 case FAST_DOUBLE_ELEMENTS: { |
| 9678 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); | 9818 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); |
| 9679 *capacity = elms->length(); | 9819 *capacity = elms->length(); |
| 9680 for (int i = 0; i < *capacity; i++) { | 9820 for (int i = 0; i < *capacity; i++) { |
| 9681 if (!elms->is_the_hole(i)) ++(*used); | 9821 if (!elms->is_the_hole(i)) ++(*used); |
| 9682 } | 9822 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 9707 (new_capacity <= kMaxUncheckedFastElementsLength && | 9847 (new_capacity <= kMaxUncheckedFastElementsLength && |
| 9708 GetHeap()->InNewSpace(this))) { | 9848 GetHeap()->InNewSpace(this))) { |
| 9709 return false; | 9849 return false; |
| 9710 } | 9850 } |
| 9711 // If the fast-case backing storage takes up roughly three times as | 9851 // If the fast-case backing storage takes up roughly three times as |
| 9712 // much space (in machine words) as a dictionary backing storage | 9852 // much space (in machine words) as a dictionary backing storage |
| 9713 // would, the object should have slow elements. | 9853 // would, the object should have slow elements. |
| 9714 int old_capacity = 0; | 9854 int old_capacity = 0; |
| 9715 int used_elements = 0; | 9855 int used_elements = 0; |
| 9716 GetElementsCapacityAndUsage(&old_capacity, &used_elements); | 9856 GetElementsCapacityAndUsage(&old_capacity, &used_elements); |
| 9717 int dictionary_size = NumberDictionary::ComputeCapacity(used_elements) * | 9857 int dictionary_size = SeededNumberDictionary::ComputeCapacity(used_elements) * |
| 9718 NumberDictionary::kEntrySize; | 9858 SeededNumberDictionary::kEntrySize; |
| 9719 return 3 * dictionary_size <= new_capacity; | 9859 return 3 * dictionary_size <= new_capacity; |
| 9720 } | 9860 } |
| 9721 | 9861 |
| 9722 | 9862 |
| 9723 bool JSObject::ShouldConvertToFastElements() { | 9863 bool JSObject::ShouldConvertToFastElements() { |
| 9724 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 9864 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
| 9725 // If the elements are sparse, we should not go back to fast case. | 9865 // If the elements are sparse, we should not go back to fast case. |
| 9726 if (!HasDenseElements()) return false; | 9866 if (!HasDenseElements()) return false; |
| 9727 // An object requiring access checks is never allowed to have fast | 9867 // An object requiring access checks is never allowed to have fast |
| 9728 // elements. If it had fast elements we would skip security checks. | 9868 // elements. If it had fast elements we would skip security checks. |
| 9729 if (IsAccessCheckNeeded()) return false; | 9869 if (IsAccessCheckNeeded()) return false; |
| 9730 | 9870 |
| 9731 FixedArray* elements = FixedArray::cast(this->elements()); | 9871 FixedArray* elements = FixedArray::cast(this->elements()); |
| 9732 NumberDictionary* dictionary = NULL; | 9872 SeededNumberDictionary* dictionary = NULL; |
| 9733 if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) { | 9873 if (elements->map() == GetHeap()->non_strict_arguments_elements_map()) { |
| 9734 dictionary = NumberDictionary::cast(elements->get(1)); | 9874 dictionary = SeededNumberDictionary::cast(elements->get(1)); |
| 9735 } else { | 9875 } else { |
| 9736 dictionary = NumberDictionary::cast(elements); | 9876 dictionary = SeededNumberDictionary::cast(elements); |
| 9737 } | 9877 } |
| 9738 // If an element has been added at a very high index in the elements | 9878 // If an element has been added at a very high index in the elements |
| 9739 // dictionary, we cannot go back to fast case. | 9879 // dictionary, we cannot go back to fast case. |
| 9740 if (dictionary->requires_slow_elements()) return false; | 9880 if (dictionary->requires_slow_elements()) return false; |
| 9741 // If the dictionary backing storage takes up roughly half as much | 9881 // If the dictionary backing storage takes up roughly half as much |
| 9742 // space (in machine words) as a fast-case backing storage would, | 9882 // space (in machine words) as a fast-case backing storage would, |
| 9743 // the object should have fast elements. | 9883 // the object should have fast elements. |
| 9744 uint32_t array_size = 0; | 9884 uint32_t array_size = 0; |
| 9745 if (IsJSArray()) { | 9885 if (IsJSArray()) { |
| 9746 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_size)); | 9886 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_size)); |
| 9747 } else { | 9887 } else { |
| 9748 array_size = dictionary->max_number_key(); | 9888 array_size = dictionary->max_number_key(); |
| 9749 } | 9889 } |
| 9750 uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) * | 9890 uint32_t dictionary_size = static_cast<uint32_t>(dictionary->Capacity()) * |
| 9751 NumberDictionary::kEntrySize; | 9891 SeededNumberDictionary::kEntrySize; |
| 9752 return 2 * dictionary_size >= array_size; | 9892 return 2 * dictionary_size >= array_size; |
| 9753 } | 9893 } |
| 9754 | 9894 |
| 9755 | 9895 |
| 9756 bool JSObject::ShouldConvertToFastDoubleElements( | 9896 bool JSObject::ShouldConvertToFastDoubleElements( |
| 9757 bool* has_smi_only_elements) { | 9897 bool* has_smi_only_elements) { |
| 9758 *has_smi_only_elements = false; | 9898 *has_smi_only_elements = false; |
| 9759 if (FLAG_unbox_double_arrays) { | 9899 if (FLAG_unbox_double_arrays) { |
| 9760 ASSERT(HasDictionaryElements()); | 9900 ASSERT(HasDictionaryElements()); |
| 9761 NumberDictionary* dictionary = NumberDictionary::cast(elements()); | 9901 SeededNumberDictionary* dictionary = |
| 9902 SeededNumberDictionary::cast(elements()); |
| 9762 bool found_double = false; | 9903 bool found_double = false; |
| 9763 for (int i = 0; i < dictionary->Capacity(); i++) { | 9904 for (int i = 0; i < dictionary->Capacity(); i++) { |
| 9764 Object* key = dictionary->KeyAt(i); | 9905 Object* key = dictionary->KeyAt(i); |
| 9765 if (key->IsNumber()) { | 9906 if (key->IsNumber()) { |
| 9766 Object* value = dictionary->ValueAt(i); | 9907 Object* value = dictionary->ValueAt(i); |
| 9767 if (!value->IsNumber()) return false; | 9908 if (!value->IsNumber()) return false; |
| 9768 if (!value->IsSmi()) { | 9909 if (!value->IsSmi()) { |
| 9769 found_double = true; | 9910 found_double = true; |
| 9770 } | 9911 } |
| 9771 } | 9912 } |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9971 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 10112 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 9972 case EXTERNAL_INT_ELEMENTS: | 10113 case EXTERNAL_INT_ELEMENTS: |
| 9973 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 10114 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 9974 case EXTERNAL_FLOAT_ELEMENTS: | 10115 case EXTERNAL_FLOAT_ELEMENTS: |
| 9975 case EXTERNAL_DOUBLE_ELEMENTS: { | 10116 case EXTERNAL_DOUBLE_ELEMENTS: { |
| 9976 ExternalArray* array = ExternalArray::cast(elements()); | 10117 ExternalArray* array = ExternalArray::cast(elements()); |
| 9977 return index < static_cast<uint32_t>(array->length()); | 10118 return index < static_cast<uint32_t>(array->length()); |
| 9978 } | 10119 } |
| 9979 case DICTIONARY_ELEMENTS: { | 10120 case DICTIONARY_ELEMENTS: { |
| 9980 return element_dictionary()->FindEntry(index) | 10121 return element_dictionary()->FindEntry(index) |
| 9981 != NumberDictionary::kNotFound; | 10122 != SeededNumberDictionary::kNotFound; |
| 9982 } | 10123 } |
| 9983 case NON_STRICT_ARGUMENTS_ELEMENTS: | 10124 case NON_STRICT_ARGUMENTS_ELEMENTS: |
| 9984 UNIMPLEMENTED(); | 10125 UNIMPLEMENTED(); |
| 9985 break; | 10126 break; |
| 9986 } | 10127 } |
| 9987 // All possibilities have been handled above already. | 10128 // All possibilities have been handled above already. |
| 9988 UNREACHABLE(); | 10129 UNREACHABLE(); |
| 9989 return GetHeap()->null_value(); | 10130 return GetHeap()->null_value(); |
| 9990 } | 10131 } |
| 9991 | 10132 |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10240 } | 10381 } |
| 10241 counter++; | 10382 counter++; |
| 10242 } | 10383 } |
| 10243 ASSERT(!storage || storage->length() >= counter); | 10384 ASSERT(!storage || storage->length() >= counter); |
| 10244 break; | 10385 break; |
| 10245 } | 10386 } |
| 10246 case DICTIONARY_ELEMENTS: { | 10387 case DICTIONARY_ELEMENTS: { |
| 10247 if (storage != NULL) { | 10388 if (storage != NULL) { |
| 10248 element_dictionary()->CopyKeysTo(storage, | 10389 element_dictionary()->CopyKeysTo(storage, |
| 10249 filter, | 10390 filter, |
| 10250 NumberDictionary::SORTED); | 10391 SeededNumberDictionary::SORTED); |
| 10251 } | 10392 } |
| 10252 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); | 10393 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); |
| 10253 break; | 10394 break; |
| 10254 } | 10395 } |
| 10255 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 10396 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
| 10256 FixedArray* parameter_map = FixedArray::cast(elements()); | 10397 FixedArray* parameter_map = FixedArray::cast(elements()); |
| 10257 int mapped_length = parameter_map->length() - 2; | 10398 int mapped_length = parameter_map->length() - 2; |
| 10258 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 10399 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 10259 if (arguments->IsDictionary()) { | 10400 if (arguments->IsDictionary()) { |
| 10260 // Copy the keys from arguments first, because Dictionary::CopyKeysTo | 10401 // Copy the keys from arguments first, because Dictionary::CopyKeysTo |
| 10261 // will insert in storage starting at index 0. | 10402 // will insert in storage starting at index 0. |
| 10262 NumberDictionary* dictionary = NumberDictionary::cast(arguments); | 10403 SeededNumberDictionary* dictionary = |
| 10404 SeededNumberDictionary::cast(arguments); |
| 10263 if (storage != NULL) { | 10405 if (storage != NULL) { |
| 10264 dictionary->CopyKeysTo(storage, filter, NumberDictionary::UNSORTED); | 10406 dictionary->CopyKeysTo( |
| 10407 storage, filter, SeededNumberDictionary::UNSORTED); |
| 10265 } | 10408 } |
| 10266 counter += dictionary->NumberOfElementsFilterAttributes(filter); | 10409 counter += dictionary->NumberOfElementsFilterAttributes(filter); |
| 10267 for (int i = 0; i < mapped_length; ++i) { | 10410 for (int i = 0; i < mapped_length; ++i) { |
| 10268 if (!parameter_map->get(i + 2)->IsTheHole()) { | 10411 if (!parameter_map->get(i + 2)->IsTheHole()) { |
| 10269 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); | 10412 if (storage != NULL) storage->set(counter, Smi::FromInt(i)); |
| 10270 ++counter; | 10413 ++counter; |
| 10271 } | 10414 } |
| 10272 } | 10415 } |
| 10273 if (storage != NULL) storage->SortPairs(storage, counter); | 10416 if (storage != NULL) storage->SortPairs(storage, counter); |
| 10274 | 10417 |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10578 public: | 10721 public: |
| 10579 explicit SubStringAsciiSymbolKey(Handle<SeqAsciiString> string, | 10722 explicit SubStringAsciiSymbolKey(Handle<SeqAsciiString> string, |
| 10580 int from, | 10723 int from, |
| 10581 int length, | 10724 int length, |
| 10582 uint32_t seed) | 10725 uint32_t seed) |
| 10583 : string_(string), from_(from), length_(length), seed_(seed) { } | 10726 : string_(string), from_(from), length_(length), seed_(seed) { } |
| 10584 | 10727 |
| 10585 uint32_t Hash() { | 10728 uint32_t Hash() { |
| 10586 ASSERT(length_ >= 0); | 10729 ASSERT(length_ >= 0); |
| 10587 ASSERT(from_ + length_ <= string_->length()); | 10730 ASSERT(from_ + length_ <= string_->length()); |
| 10588 StringHasher hasher(length_, string_->GetHeap()->StringHashSeed()); | 10731 StringHasher hasher(length_, string_->GetHeap()->HashSeed()); |
| 10589 | 10732 |
| 10590 // Very long strings have a trivial hash that doesn't inspect the | 10733 // Very long strings have a trivial hash that doesn't inspect the |
| 10591 // string contents. | 10734 // string contents. |
| 10592 if (hasher.has_trivial_hash()) { | 10735 if (hasher.has_trivial_hash()) { |
| 10593 hash_field_ = hasher.GetHashField(); | 10736 hash_field_ = hasher.GetHashField(); |
| 10594 } else { | 10737 } else { |
| 10595 int i = 0; | 10738 int i = 0; |
| 10596 // Do the iterative array index computation as long as there is a | 10739 // Do the iterative array index computation as long as there is a |
| 10597 // chance this is an array index. | 10740 // chance this is an array index. |
| 10598 while (i < length_ && hasher.is_array_index()) { | 10741 while (i < length_ && hasher.is_array_index()) { |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10787 i++) { | 10930 i++) { |
| 10788 new_table->set(i, get(i), mode); | 10931 new_table->set(i, get(i), mode); |
| 10789 } | 10932 } |
| 10790 | 10933 |
| 10791 // Rehash the elements. | 10934 // Rehash the elements. |
| 10792 int capacity = Capacity(); | 10935 int capacity = Capacity(); |
| 10793 for (int i = 0; i < capacity; i++) { | 10936 for (int i = 0; i < capacity; i++) { |
| 10794 uint32_t from_index = EntryToIndex(i); | 10937 uint32_t from_index = EntryToIndex(i); |
| 10795 Object* k = get(from_index); | 10938 Object* k = get(from_index); |
| 10796 if (IsKey(k)) { | 10939 if (IsKey(k)) { |
| 10797 uint32_t hash = Shape::HashForObject(key, k); | 10940 uint32_t hash = HashTable<Shape, Key>::HashForObject(key, k); |
| 10798 uint32_t insertion_index = | 10941 uint32_t insertion_index = |
| 10799 EntryToIndex(new_table->FindInsertionEntry(hash)); | 10942 EntryToIndex(new_table->FindInsertionEntry(hash)); |
| 10800 for (int j = 0; j < Shape::kEntrySize; j++) { | 10943 for (int j = 0; j < Shape::kEntrySize; j++) { |
| 10801 new_table->set(insertion_index + j, get(from_index + j), mode); | 10944 new_table->set(insertion_index + j, get(from_index + j), mode); |
| 10802 } | 10945 } |
| 10803 } | 10946 } |
| 10804 } | 10947 } |
| 10805 new_table->SetNumberOfElements(NumberOfElements()); | 10948 new_table->SetNumberOfElements(NumberOfElements()); |
| 10806 new_table->SetNumberOfDeletedElements(0); | 10949 new_table->SetNumberOfDeletedElements(0); |
| 10807 return new_table; | 10950 return new_table; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10885 template class HashTable<CompilationCacheShape, HashTableKey*>; | 11028 template class HashTable<CompilationCacheShape, HashTableKey*>; |
| 10886 | 11029 |
| 10887 template class HashTable<MapCacheShape, HashTableKey*>; | 11030 template class HashTable<MapCacheShape, HashTableKey*>; |
| 10888 | 11031 |
| 10889 template class HashTable<ObjectHashTableShape<1>, Object*>; | 11032 template class HashTable<ObjectHashTableShape<1>, Object*>; |
| 10890 | 11033 |
| 10891 template class HashTable<ObjectHashTableShape<2>, Object*>; | 11034 template class HashTable<ObjectHashTableShape<2>, Object*>; |
| 10892 | 11035 |
| 10893 template class Dictionary<StringDictionaryShape, String*>; | 11036 template class Dictionary<StringDictionaryShape, String*>; |
| 10894 | 11037 |
| 10895 template class Dictionary<NumberDictionaryShape, uint32_t>; | 11038 template class Dictionary<SeededNumberDictionaryShape, uint32_t>; |
| 10896 | 11039 |
| 10897 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate( | 11040 template class Dictionary<UnseededNumberDictionaryShape, uint32_t>; |
| 10898 int); | 11041 |
| 11042 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 11043 Allocate(int at_least_space_for); |
| 11044 |
| 11045 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| 11046 Allocate(int at_least_space_for); |
| 10899 | 11047 |
| 10900 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( | 11048 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate( |
| 10901 int); | 11049 int); |
| 10902 | 11050 |
| 10903 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AtPut( | 11051 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::AtPut( |
| 10904 uint32_t, Object*); | 11052 uint32_t, Object*); |
| 10905 | 11053 |
| 10906 template Object* Dictionary<NumberDictionaryShape, uint32_t>::SlowReverseLookup( | 11054 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| 10907 Object*); | 11055 AtPut(uint32_t, Object*); |
| 11056 |
| 11057 template Object* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| 11058 SlowReverseLookup(Object* value); |
| 10908 | 11059 |
| 10909 template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup( | 11060 template Object* Dictionary<StringDictionaryShape, String*>::SlowReverseLookup( |
| 10910 Object*); | 11061 Object*); |
| 10911 | 11062 |
| 10912 template void Dictionary<NumberDictionaryShape, uint32_t>::CopyKeysTo( | 11063 template void Dictionary<SeededNumberDictionaryShape, uint32_t>::CopyKeysTo( |
| 10913 FixedArray*, | 11064 FixedArray*, |
| 10914 PropertyAttributes, | 11065 PropertyAttributes, |
| 10915 Dictionary<NumberDictionaryShape, uint32_t>::SortMode); | 11066 Dictionary<SeededNumberDictionaryShape, uint32_t>::SortMode); |
| 10916 | 11067 |
| 10917 template Object* Dictionary<StringDictionaryShape, String*>::DeleteProperty( | 11068 template Object* Dictionary<StringDictionaryShape, String*>::DeleteProperty( |
| 10918 int, JSObject::DeleteMode); | 11069 int, JSObject::DeleteMode); |
| 10919 | 11070 |
| 10920 template Object* Dictionary<NumberDictionaryShape, uint32_t>::DeleteProperty( | 11071 template Object* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 10921 int, JSObject::DeleteMode); | 11072 DeleteProperty(int, JSObject::DeleteMode); |
| 10922 | 11073 |
| 10923 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Shrink( | 11074 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Shrink( |
| 10924 String*); | 11075 String*); |
| 10925 | 11076 |
| 10926 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Shrink( | 11077 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Shrink( |
| 10927 uint32_t); | 11078 uint32_t); |
| 10928 | 11079 |
| 10929 template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo( | 11080 template void Dictionary<StringDictionaryShape, String*>::CopyKeysTo( |
| 10930 FixedArray*, | 11081 FixedArray*, |
| 10931 int, | 11082 int, |
| 10932 Dictionary<StringDictionaryShape, String*>::SortMode); | 11083 Dictionary<StringDictionaryShape, String*>::SortMode); |
| 10933 | 11084 |
| 10934 template int | 11085 template int |
| 10935 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes( | 11086 Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes( |
| 10936 PropertyAttributes); | 11087 PropertyAttributes); |
| 10937 | 11088 |
| 10938 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add( | 11089 template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add( |
| 10939 String*, Object*, PropertyDetails); | 11090 String*, Object*, PropertyDetails); |
| 10940 | 11091 |
| 10941 template MaybeObject* | 11092 template MaybeObject* |
| 10942 Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices(); | 11093 Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices(); |
| 10943 | 11094 |
| 10944 template int | 11095 template int |
| 10945 Dictionary<NumberDictionaryShape, uint32_t>::NumberOfElementsFilterAttributes( | 11096 Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 10946 PropertyAttributes); | 11097 NumberOfElementsFilterAttributes(PropertyAttributes); |
| 10947 | 11098 |
| 10948 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Add( | 11099 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>::Add( |
| 10949 uint32_t, Object*, PropertyDetails); | 11100 uint32_t, Object*, PropertyDetails); |
| 10950 | 11101 |
| 10951 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>:: | 11102 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>::Add( |
| 11103 uint32_t, Object*, PropertyDetails); |
| 11104 |
| 11105 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 11106 EnsureCapacity(int, uint32_t); |
| 11107 |
| 11108 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| 10952 EnsureCapacity(int, uint32_t); | 11109 EnsureCapacity(int, uint32_t); |
| 10953 | 11110 |
| 10954 template MaybeObject* Dictionary<StringDictionaryShape, String*>:: | 11111 template MaybeObject* Dictionary<StringDictionaryShape, String*>:: |
| 10955 EnsureCapacity(int, String*); | 11112 EnsureCapacity(int, String*); |
| 10956 | 11113 |
| 10957 template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AddEntry( | 11114 template MaybeObject* Dictionary<SeededNumberDictionaryShape, uint32_t>:: |
| 10958 uint32_t, Object*, PropertyDetails, uint32_t); | 11115 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
| 11116 |
| 11117 template MaybeObject* Dictionary<UnseededNumberDictionaryShape, uint32_t>:: |
| 11118 AddEntry(uint32_t, Object*, PropertyDetails, uint32_t); |
| 10959 | 11119 |
| 10960 template MaybeObject* Dictionary<StringDictionaryShape, String*>::AddEntry( | 11120 template MaybeObject* Dictionary<StringDictionaryShape, String*>::AddEntry( |
| 10961 String*, Object*, PropertyDetails, uint32_t); | 11121 String*, Object*, PropertyDetails, uint32_t); |
| 10962 | 11122 |
| 10963 template | 11123 template |
| 10964 int Dictionary<NumberDictionaryShape, uint32_t>::NumberOfEnumElements(); | 11124 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements(); |
| 10965 | 11125 |
| 10966 template | 11126 template |
| 10967 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); | 11127 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); |
| 10968 | 11128 |
| 10969 template | 11129 template |
| 10970 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t); | 11130 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t); |
| 10971 | 11131 |
| 10972 | 11132 |
| 10973 // Collates undefined and unexisting elements below limit from position | 11133 // Collates undefined and unexisting elements below limit from position |
| 10974 // zero of the elements. The object stays in Dictionary mode. | 11134 // zero of the elements. The object stays in Dictionary mode. |
| 10975 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { | 11135 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { |
| 10976 ASSERT(HasDictionaryElements()); | 11136 ASSERT(HasDictionaryElements()); |
| 10977 // Must stay in dictionary mode, either because of requires_slow_elements, | 11137 // Must stay in dictionary mode, either because of requires_slow_elements, |
| 10978 // or because we are not going to sort (and therefore compact) all of the | 11138 // or because we are not going to sort (and therefore compact) all of the |
| 10979 // elements. | 11139 // elements. |
| 10980 NumberDictionary* dict = element_dictionary(); | 11140 SeededNumberDictionary* dict = element_dictionary(); |
| 10981 HeapNumber* result_double = NULL; | 11141 HeapNumber* result_double = NULL; |
| 10982 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { | 11142 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { |
| 10983 // Allocate space for result before we start mutating the object. | 11143 // Allocate space for result before we start mutating the object. |
| 10984 Object* new_double; | 11144 Object* new_double; |
| 10985 { MaybeObject* maybe_new_double = GetHeap()->AllocateHeapNumber(0.0); | 11145 { MaybeObject* maybe_new_double = GetHeap()->AllocateHeapNumber(0.0); |
| 10986 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; | 11146 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; |
| 10987 } | 11147 } |
| 10988 result_double = HeapNumber::cast(new_double); | 11148 result_double = HeapNumber::cast(new_double); |
| 10989 } | 11149 } |
| 10990 | 11150 |
| 10991 Object* obj; | 11151 Object* obj; |
| 10992 { MaybeObject* maybe_obj = | 11152 { MaybeObject* maybe_obj = |
| 10993 NumberDictionary::Allocate(dict->NumberOfElements()); | 11153 SeededNumberDictionary::Allocate(dict->NumberOfElements()); |
| 10994 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 11154 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 10995 } | 11155 } |
| 10996 NumberDictionary* new_dict = NumberDictionary::cast(obj); | 11156 SeededNumberDictionary* new_dict = SeededNumberDictionary::cast(obj); |
| 10997 | 11157 |
| 10998 AssertNoAllocation no_alloc; | 11158 AssertNoAllocation no_alloc; |
| 10999 | 11159 |
| 11000 uint32_t pos = 0; | 11160 uint32_t pos = 0; |
| 11001 uint32_t undefs = 0; | 11161 uint32_t undefs = 0; |
| 11002 int capacity = dict->Capacity(); | 11162 int capacity = dict->Capacity(); |
| 11003 for (int i = 0; i < capacity; i++) { | 11163 for (int i = 0; i < capacity; i++) { |
| 11004 Object* k = dict->KeyAt(i); | 11164 Object* k = dict->KeyAt(i); |
| 11005 if (dict->IsKey(k)) { | 11165 if (dict->IsKey(k)) { |
| 11006 ASSERT(k->IsNumber()); | 11166 ASSERT(k->IsNumber()); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11070 // Collects all defined (non-hole) and non-undefined (array) elements at | 11230 // Collects all defined (non-hole) and non-undefined (array) elements at |
| 11071 // the start of the elements array. | 11231 // the start of the elements array. |
| 11072 // If the object is in dictionary mode, it is converted to fast elements | 11232 // If the object is in dictionary mode, it is converted to fast elements |
| 11073 // mode. | 11233 // mode. |
| 11074 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { | 11234 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { |
| 11075 Heap* heap = GetHeap(); | 11235 Heap* heap = GetHeap(); |
| 11076 | 11236 |
| 11077 if (HasDictionaryElements()) { | 11237 if (HasDictionaryElements()) { |
| 11078 // Convert to fast elements containing only the existing properties. | 11238 // Convert to fast elements containing only the existing properties. |
| 11079 // Ordering is irrelevant, since we are going to sort anyway. | 11239 // Ordering is irrelevant, since we are going to sort anyway. |
| 11080 NumberDictionary* dict = element_dictionary(); | 11240 SeededNumberDictionary* dict = element_dictionary(); |
| 11081 if (IsJSArray() || dict->requires_slow_elements() || | 11241 if (IsJSArray() || dict->requires_slow_elements() || |
| 11082 dict->max_number_key() >= limit) { | 11242 dict->max_number_key() >= limit) { |
| 11083 return PrepareSlowElementsForSort(limit); | 11243 return PrepareSlowElementsForSort(limit); |
| 11084 } | 11244 } |
| 11085 // Convert to fast elements. | 11245 // Convert to fast elements. |
| 11086 | 11246 |
| 11087 Object* obj; | 11247 Object* obj; |
| 11088 { MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS); | 11248 { MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS); |
| 11089 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 11249 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 11090 } | 11250 } |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11437 hash += hash << 10; | 11597 hash += hash << 10; |
| 11438 hash ^= hash >> 6; | 11598 hash ^= hash >> 6; |
| 11439 // Char 2. | 11599 // Char 2. |
| 11440 hash += c2; | 11600 hash += c2; |
| 11441 hash += hash << 10; | 11601 hash += hash << 10; |
| 11442 hash ^= hash >> 6; | 11602 hash ^= hash >> 6; |
| 11443 // GetHash. | 11603 // GetHash. |
| 11444 hash += hash << 3; | 11604 hash += hash << 3; |
| 11445 hash ^= hash >> 11; | 11605 hash ^= hash >> 11; |
| 11446 hash += hash << 15; | 11606 hash += hash << 15; |
| 11447 if ((hash & String::kHashBitMask) == 0) hash = 27; | 11607 if ((hash & String::kHashBitMask) == 0) hash = String::kZeroHash; |
| 11448 #ifdef DEBUG | 11608 #ifdef DEBUG |
| 11449 StringHasher hasher(2, seed); | 11609 StringHasher hasher(2, seed); |
| 11450 hasher.AddCharacter(c1); | 11610 hasher.AddCharacter(c1); |
| 11451 hasher.AddCharacter(c2); | 11611 hasher.AddCharacter(c2); |
| 11452 // If this assert fails then we failed to reproduce the two-character | 11612 // If this assert fails then we failed to reproduce the two-character |
| 11453 // version of the string hashing algorithm above. One reason could be | 11613 // version of the string hashing algorithm above. One reason could be |
| 11454 // that we were passed two digits as characters, since the hash | 11614 // that we were passed two digits as characters, since the hash |
| 11455 // algorithm is different in that case. | 11615 // algorithm is different in that case. |
| 11456 ASSERT_EQ(static_cast<int>(hasher.GetHash()), static_cast<int>(hash)); | 11616 ASSERT_EQ(static_cast<int>(hasher.GetHash()), static_cast<int>(hash)); |
| 11457 #endif | 11617 #endif |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11496 ASSERT(StringShape(result).IsSymbol()); | 11656 ASSERT(StringShape(result).IsSymbol()); |
| 11497 *symbol = result; | 11657 *symbol = result; |
| 11498 return true; | 11658 return true; |
| 11499 } | 11659 } |
| 11500 } | 11660 } |
| 11501 | 11661 |
| 11502 | 11662 |
| 11503 bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1, | 11663 bool SymbolTable::LookupTwoCharsSymbolIfExists(uint32_t c1, |
| 11504 uint32_t c2, | 11664 uint32_t c2, |
| 11505 String** symbol) { | 11665 String** symbol) { |
| 11506 TwoCharHashTableKey key(c1, c2, GetHeap()->StringHashSeed()); | 11666 TwoCharHashTableKey key(c1, c2, GetHeap()->HashSeed()); |
| 11507 int entry = FindEntry(&key); | 11667 int entry = FindEntry(&key); |
| 11508 if (entry == kNotFound) { | 11668 if (entry == kNotFound) { |
| 11509 return false; | 11669 return false; |
| 11510 } else { | 11670 } else { |
| 11511 String* result = String::cast(KeyAt(entry)); | 11671 String* result = String::cast(KeyAt(entry)); |
| 11512 ASSERT(StringShape(result).IsSymbol()); | 11672 ASSERT(StringShape(result).IsSymbol()); |
| 11513 *symbol = result; | 11673 *symbol = result; |
| 11514 return true; | 11674 return true; |
| 11515 } | 11675 } |
| 11516 } | 11676 } |
| 11517 | 11677 |
| 11518 | 11678 |
| 11519 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, | 11679 MaybeObject* SymbolTable::LookupSymbol(Vector<const char> str, |
| 11520 Object** s) { | 11680 Object** s) { |
| 11521 Utf8SymbolKey key(str, GetHeap()->StringHashSeed()); | 11681 Utf8SymbolKey key(str, GetHeap()->HashSeed()); |
| 11522 return LookupKey(&key, s); | 11682 return LookupKey(&key, s); |
| 11523 } | 11683 } |
| 11524 | 11684 |
| 11525 | 11685 |
| 11526 MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str, | 11686 MaybeObject* SymbolTable::LookupAsciiSymbol(Vector<const char> str, |
| 11527 Object** s) { | 11687 Object** s) { |
| 11528 AsciiSymbolKey key(str, GetHeap()->StringHashSeed()); | 11688 AsciiSymbolKey key(str, GetHeap()->HashSeed()); |
| 11529 return LookupKey(&key, s); | 11689 return LookupKey(&key, s); |
| 11530 } | 11690 } |
| 11531 | 11691 |
| 11532 | 11692 |
| 11533 MaybeObject* SymbolTable::LookupSubStringAsciiSymbol(Handle<SeqAsciiString> str, | 11693 MaybeObject* SymbolTable::LookupSubStringAsciiSymbol(Handle<SeqAsciiString> str, |
| 11534 int from, | 11694 int from, |
| 11535 int length, | 11695 int length, |
| 11536 Object** s) { | 11696 Object** s) { |
| 11537 SubStringAsciiSymbolKey key(str, from, length, GetHeap()->StringHashSeed()); | 11697 SubStringAsciiSymbolKey key(str, from, length, GetHeap()->HashSeed()); |
| 11538 return LookupKey(&key, s); | 11698 return LookupKey(&key, s); |
| 11539 } | 11699 } |
| 11540 | 11700 |
| 11541 | 11701 |
| 11542 MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str, | 11702 MaybeObject* SymbolTable::LookupTwoByteSymbol(Vector<const uc16> str, |
| 11543 Object** s) { | 11703 Object** s) { |
| 11544 TwoByteSymbolKey key(str, GetHeap()->StringHashSeed()); | 11704 TwoByteSymbolKey key(str, GetHeap()->HashSeed()); |
| 11545 return LookupKey(&key, s); | 11705 return LookupKey(&key, s); |
| 11546 } | 11706 } |
| 11547 | 11707 |
| 11548 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { | 11708 MaybeObject* SymbolTable::LookupKey(HashTableKey* key, Object** s) { |
| 11549 int entry = FindEntry(key); | 11709 int entry = FindEntry(key); |
| 11550 | 11710 |
| 11551 // Symbol already in table. | 11711 // Symbol already in table. |
| 11552 if (entry != kNotFound) { | 11712 if (entry != kNotFound) { |
| 11553 *s = KeyAt(entry); | 11713 *s = KeyAt(entry); |
| 11554 return this; | 11714 return this; |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11873 Object* obj; | 12033 Object* obj; |
| 11874 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 12034 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| 11875 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 12035 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 11876 } | 12036 } |
| 11877 | 12037 |
| 11878 Object* k; | 12038 Object* k; |
| 11879 { MaybeObject* maybe_k = Shape::AsObject(key); | 12039 { MaybeObject* maybe_k = Shape::AsObject(key); |
| 11880 if (!maybe_k->ToObject(&k)) return maybe_k; | 12040 if (!maybe_k->ToObject(&k)) return maybe_k; |
| 11881 } | 12041 } |
| 11882 PropertyDetails details = PropertyDetails(NONE, NORMAL); | 12042 PropertyDetails details = PropertyDetails(NONE, NORMAL); |
| 11883 return Dictionary<Shape, Key>::cast(obj)-> | 12043 |
| 11884 AddEntry(key, value, details, Shape::Hash(key)); | 12044 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details, |
| 12045 Dictionary<Shape, Key>::Hash(key)); |
| 11885 } | 12046 } |
| 11886 | 12047 |
| 11887 | 12048 |
| 11888 template<typename Shape, typename Key> | 12049 template<typename Shape, typename Key> |
| 11889 MaybeObject* Dictionary<Shape, Key>::Add(Key key, | 12050 MaybeObject* Dictionary<Shape, Key>::Add(Key key, |
| 11890 Object* value, | 12051 Object* value, |
| 11891 PropertyDetails details) { | 12052 PropertyDetails details) { |
| 11892 // Valdate key is absent. | 12053 // Valdate key is absent. |
| 11893 SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound)); | 12054 SLOW_ASSERT((this->FindEntry(key) == Dictionary<Shape, Key>::kNotFound)); |
| 11894 // Check whether the dictionary should be extended. | 12055 // Check whether the dictionary should be extended. |
| 11895 Object* obj; | 12056 Object* obj; |
| 11896 { MaybeObject* maybe_obj = EnsureCapacity(1, key); | 12057 { MaybeObject* maybe_obj = EnsureCapacity(1, key); |
| 11897 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 12058 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 11898 } | 12059 } |
| 11899 return Dictionary<Shape, Key>::cast(obj)-> | 12060 |
| 11900 AddEntry(key, value, details, Shape::Hash(key)); | 12061 return Dictionary<Shape, Key>::cast(obj)->AddEntry(key, value, details, |
| 12062 Dictionary<Shape, Key>::Hash(key)); |
| 11901 } | 12063 } |
| 11902 | 12064 |
| 11903 | 12065 |
| 11904 // Add a key, value pair to the dictionary. | 12066 // Add a key, value pair to the dictionary. |
| 11905 template<typename Shape, typename Key> | 12067 template<typename Shape, typename Key> |
| 11906 MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key, | 12068 MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key, |
| 11907 Object* value, | 12069 Object* value, |
| 11908 PropertyDetails details, | 12070 PropertyDetails details, |
| 11909 uint32_t hash) { | 12071 uint32_t hash) { |
| 11910 // Compute the key object. | 12072 // Compute the key object. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 11923 SetNextEnumerationIndex(index + 1); | 12085 SetNextEnumerationIndex(index + 1); |
| 11924 } | 12086 } |
| 11925 SetEntry(entry, k, value, details); | 12087 SetEntry(entry, k, value, details); |
| 11926 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() | 12088 ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber() |
| 11927 || Dictionary<Shape, Key>::KeyAt(entry)->IsString())); | 12089 || Dictionary<Shape, Key>::KeyAt(entry)->IsString())); |
| 11928 HashTable<Shape, Key>::ElementAdded(); | 12090 HashTable<Shape, Key>::ElementAdded(); |
| 11929 return this; | 12091 return this; |
| 11930 } | 12092 } |
| 11931 | 12093 |
| 11932 | 12094 |
| 11933 void NumberDictionary::UpdateMaxNumberKey(uint32_t key) { | 12095 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { |
| 11934 // If the dictionary requires slow elements an element has already | 12096 // If the dictionary requires slow elements an element has already |
| 11935 // been added at a high index. | 12097 // been added at a high index. |
| 11936 if (requires_slow_elements()) return; | 12098 if (requires_slow_elements()) return; |
| 11937 // Check if this index is high enough that we should require slow | 12099 // Check if this index is high enough that we should require slow |
| 11938 // elements. | 12100 // elements. |
| 11939 if (key > kRequiresSlowElementsLimit) { | 12101 if (key > kRequiresSlowElementsLimit) { |
| 11940 set_requires_slow_elements(); | 12102 set_requires_slow_elements(); |
| 11941 return; | 12103 return; |
| 11942 } | 12104 } |
| 11943 // Update max key value. | 12105 // Update max key value. |
| 11944 Object* max_index_object = get(kMaxNumberKeyIndex); | 12106 Object* max_index_object = get(kMaxNumberKeyIndex); |
| 11945 if (!max_index_object->IsSmi() || max_number_key() < key) { | 12107 if (!max_index_object->IsSmi() || max_number_key() < key) { |
| 11946 FixedArray::set(kMaxNumberKeyIndex, | 12108 FixedArray::set(kMaxNumberKeyIndex, |
| 11947 Smi::FromInt(key << kRequiresSlowElementsTagSize)); | 12109 Smi::FromInt(key << kRequiresSlowElementsTagSize)); |
| 11948 } | 12110 } |
| 11949 } | 12111 } |
| 11950 | 12112 |
| 11951 | 12113 |
| 11952 MaybeObject* NumberDictionary::AddNumberEntry(uint32_t key, | 12114 MaybeObject* SeededNumberDictionary::AddNumberEntry(uint32_t key, |
| 11953 Object* value, | 12115 Object* value, |
| 11954 PropertyDetails details) { | 12116 PropertyDetails details) { |
| 11955 UpdateMaxNumberKey(key); | 12117 UpdateMaxNumberKey(key); |
| 11956 SLOW_ASSERT(this->FindEntry(key) == kNotFound); | 12118 SLOW_ASSERT(this->FindEntry(key) == kNotFound); |
| 11957 return Add(key, value, details); | 12119 return Add(key, value, details); |
| 11958 } | 12120 } |
| 11959 | 12121 |
| 11960 | 12122 |
| 11961 MaybeObject* NumberDictionary::AtNumberPut(uint32_t key, Object* value) { | 12123 MaybeObject* UnseededNumberDictionary::AddNumberEntry(uint32_t key, |
| 12124 Object* value) { |
| 12125 SLOW_ASSERT(this->FindEntry(key) == kNotFound); |
| 12126 return Add(key, value, PropertyDetails(NONE, NORMAL)); |
| 12127 } |
| 12128 |
| 12129 |
| 12130 MaybeObject* SeededNumberDictionary::AtNumberPut(uint32_t key, Object* value) { |
| 11962 UpdateMaxNumberKey(key); | 12131 UpdateMaxNumberKey(key); |
| 11963 return AtPut(key, value); | 12132 return AtPut(key, value); |
| 11964 } | 12133 } |
| 11965 | 12134 |
| 11966 | 12135 |
| 11967 MaybeObject* NumberDictionary::Set(uint32_t key, | 12136 MaybeObject* UnseededNumberDictionary::AtNumberPut(uint32_t key, |
| 11968 Object* value, | 12137 Object* value) { |
| 11969 PropertyDetails details) { | 12138 return AtPut(key, value); |
| 12139 } |
| 12140 |
| 12141 |
| 12142 Handle<SeededNumberDictionary> SeededNumberDictionary::Set( |
| 12143 Handle<SeededNumberDictionary> dictionary, |
| 12144 uint32_t index, |
| 12145 Handle<Object> value, |
| 12146 PropertyDetails details) { |
| 12147 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), |
| 12148 dictionary->Set(index, *value, details), |
| 12149 SeededNumberDictionary); |
| 12150 } |
| 12151 |
| 12152 |
| 12153 Handle<UnseededNumberDictionary> UnseededNumberDictionary::Set( |
| 12154 Handle<UnseededNumberDictionary> dictionary, |
| 12155 uint32_t index, |
| 12156 Handle<Object> value) { |
| 12157 CALL_HEAP_FUNCTION(dictionary->GetIsolate(), |
| 12158 dictionary->Set(index, *value), |
| 12159 UnseededNumberDictionary); |
| 12160 } |
| 12161 |
| 12162 |
| 12163 MaybeObject* SeededNumberDictionary::Set(uint32_t key, |
| 12164 Object* value, |
| 12165 PropertyDetails details) { |
| 11970 int entry = FindEntry(key); | 12166 int entry = FindEntry(key); |
| 11971 if (entry == kNotFound) return AddNumberEntry(key, value, details); | 12167 if (entry == kNotFound) return AddNumberEntry(key, value, details); |
| 11972 // Preserve enumeration index. | 12168 // Preserve enumeration index. |
| 11973 details = PropertyDetails(details.attributes(), | 12169 details = PropertyDetails(details.attributes(), |
| 11974 details.type(), | 12170 details.type(), |
| 11975 DetailsAt(entry).index()); | 12171 DetailsAt(entry).index()); |
| 11976 MaybeObject* maybe_object_key = NumberDictionaryShape::AsObject(key); | 12172 MaybeObject* maybe_object_key = SeededNumberDictionaryShape::AsObject(key); |
| 11977 Object* object_key; | 12173 Object* object_key; |
| 11978 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; | 12174 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; |
| 11979 SetEntry(entry, object_key, value, details); | 12175 SetEntry(entry, object_key, value, details); |
| 11980 return this; | 12176 return this; |
| 11981 } | 12177 } |
| 11982 | 12178 |
| 11983 | 12179 |
| 12180 MaybeObject* UnseededNumberDictionary::Set(uint32_t key, |
| 12181 Object* value) { |
| 12182 int entry = FindEntry(key); |
| 12183 if (entry == kNotFound) return AddNumberEntry(key, value); |
| 12184 MaybeObject* maybe_object_key = UnseededNumberDictionaryShape::AsObject(key); |
| 12185 Object* object_key; |
| 12186 if (!maybe_object_key->ToObject(&object_key)) return maybe_object_key; |
| 12187 SetEntry(entry, object_key, value); |
| 12188 return this; |
| 12189 } |
| 12190 |
| 12191 |
| 11984 | 12192 |
| 11985 template<typename Shape, typename Key> | 12193 template<typename Shape, typename Key> |
| 11986 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( | 12194 int Dictionary<Shape, Key>::NumberOfElementsFilterAttributes( |
| 11987 PropertyAttributes filter) { | 12195 PropertyAttributes filter) { |
| 11988 int capacity = HashTable<Shape, Key>::Capacity(); | 12196 int capacity = HashTable<Shape, Key>::Capacity(); |
| 11989 int result = 0; | 12197 int result = 0; |
| 11990 for (int i = 0; i < capacity; i++) { | 12198 for (int i = 0; i < capacity; i++) { |
| 11991 Object* k = HashTable<Shape, Key>::KeyAt(i); | 12199 Object* k = HashTable<Shape, Key>::KeyAt(i); |
| 11992 if (HashTable<Shape, Key>::IsKey(k)) { | 12200 if (HashTable<Shape, Key>::IsKey(k)) { |
| 11993 PropertyDetails details = DetailsAt(i); | 12201 PropertyDetails details = DetailsAt(i); |
| (...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12598 if (break_point_objects()->IsUndefined()) return 0; | 12806 if (break_point_objects()->IsUndefined()) return 0; |
| 12599 // Single break point. | 12807 // Single break point. |
| 12600 if (!break_point_objects()->IsFixedArray()) return 1; | 12808 if (!break_point_objects()->IsFixedArray()) return 1; |
| 12601 // Multiple break points. | 12809 // Multiple break points. |
| 12602 return FixedArray::cast(break_point_objects())->length(); | 12810 return FixedArray::cast(break_point_objects())->length(); |
| 12603 } | 12811 } |
| 12604 #endif // ENABLE_DEBUGGER_SUPPORT | 12812 #endif // ENABLE_DEBUGGER_SUPPORT |
| 12605 | 12813 |
| 12606 | 12814 |
| 12607 } } // namespace v8::internal | 12815 } } // namespace v8::internal |
| OLD | NEW |