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 |