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

Side by Side Diff: src/objects.cc

Issue 9227007: Version 3.8.6 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698