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

Side by Side Diff: src/objects.cc

Issue 7901016: Basic support for tracking smi-only arrays on ia32. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: ready to land Created 9 years, 3 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3045 matching lines...) Expand 10 before | Expand all | Expand 10 after
3056 FixedArrayBase* array = FixedArrayBase::cast(elements()); 3056 FixedArrayBase* array = FixedArrayBase::cast(elements());
3057 Map* old_map = array->map(); 3057 Map* old_map = array->map();
3058 bool is_arguments = 3058 bool is_arguments =
3059 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map()); 3059 (old_map == old_map->GetHeap()->non_strict_arguments_elements_map());
3060 if (is_arguments) { 3060 if (is_arguments) {
3061 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1)); 3061 array = FixedArrayBase::cast(FixedArray::cast(array)->get(1));
3062 } 3062 }
3063 if (array->IsDictionary()) return array; 3063 if (array->IsDictionary()) return array;
3064 3064
3065 ASSERT(HasFastElements() || 3065 ASSERT(HasFastElements() ||
3066 HasFastSmiOnlyElements() ||
3066 HasFastDoubleElements() || 3067 HasFastDoubleElements() ||
3067 HasFastArgumentsElements()); 3068 HasFastArgumentsElements());
3068 // Compute the effective length and allocate a new backing store. 3069 // Compute the effective length and allocate a new backing store.
3069 int length = IsJSArray() 3070 int length = IsJSArray()
3070 ? Smi::cast(JSArray::cast(this)->length())->value() 3071 ? Smi::cast(JSArray::cast(this)->length())->value()
3071 : array->length(); 3072 : array->length();
3072 int old_capacity = 0; 3073 int old_capacity = 0;
3073 int used_elements = 0; 3074 int used_elements = 0;
3074 GetElementsCapacityAndUsage(&old_capacity, &used_elements); 3075 GetElementsCapacityAndUsage(&old_capacity, &used_elements);
3075 NumberDictionary* dictionary = NULL; 3076 NumberDictionary* dictionary = NULL;
(...skipping 14 matching lines...) Expand all
3090 } else { 3091 } else {
3091 // Objects must be allocated in the old object space, since the 3092 // Objects must be allocated in the old object space, since the
3092 // overall number of HeapNumbers needed for the conversion might 3093 // overall number of HeapNumbers needed for the conversion might
3093 // exceed the capacity of new space, and we would fail repeatedly 3094 // exceed the capacity of new space, and we would fail repeatedly
3094 // trying to convert the FixedDoubleArray. 3095 // trying to convert the FixedDoubleArray.
3095 MaybeObject* maybe_value_object = 3096 MaybeObject* maybe_value_object =
3096 GetHeap()->AllocateHeapNumber(double_array->get_scalar(i), TENURED); 3097 GetHeap()->AllocateHeapNumber(double_array->get_scalar(i), TENURED);
3097 if (!maybe_value_object->ToObject(&value)) return maybe_value_object; 3098 if (!maybe_value_object->ToObject(&value)) return maybe_value_object;
3098 } 3099 }
3099 } else { 3100 } else {
3100 ASSERT(old_map->has_fast_elements()); 3101 ASSERT(old_map->has_fast_elements() ||
3102 old_map->has_fast_smi_only_elements());
3101 value = FixedArray::cast(array)->get(i); 3103 value = FixedArray::cast(array)->get(i);
3102 } 3104 }
3103 PropertyDetails details = PropertyDetails(NONE, NORMAL); 3105 PropertyDetails details = PropertyDetails(NONE, NORMAL);
3104 if (!value->IsTheHole()) { 3106 if (!value->IsTheHole()) {
3105 Object* result; 3107 Object* result;
3106 MaybeObject* maybe_result = 3108 MaybeObject* maybe_result =
3107 dictionary->AddNumberEntry(i, value, details); 3109 dictionary->AddNumberEntry(i, value, details);
3108 if (!maybe_result->ToObject(&result)) return maybe_result; 3110 if (!maybe_result->ToObject(&result)) return maybe_result;
3109 dictionary = NumberDictionary::cast(result); 3111 dictionary = NumberDictionary::cast(result);
3110 } 3112 }
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
3405 } 3407 }
3406 // Make sure the properties are normalized before removing the entry. 3408 // Make sure the properties are normalized before removing the entry.
3407 return DeleteNormalizedProperty(name, mode); 3409 return DeleteNormalizedProperty(name, mode);
3408 } 3410 }
3409 } 3411 }
3410 3412
3411 3413
3412 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, 3414 bool JSObject::ReferencesObjectFromElements(FixedArray* elements,
3413 ElementsKind kind, 3415 ElementsKind kind,
3414 Object* object) { 3416 Object* object) {
3415 ASSERT(kind == FAST_ELEMENTS || kind == DICTIONARY_ELEMENTS); 3417 ASSERT(kind == FAST_ELEMENTS ||
3418 kind == DICTIONARY_ELEMENTS);
3416 if (kind == FAST_ELEMENTS) { 3419 if (kind == FAST_ELEMENTS) {
3417 int length = IsJSArray() 3420 int length = IsJSArray()
3418 ? Smi::cast(JSArray::cast(this)->length())->value() 3421 ? Smi::cast(JSArray::cast(this)->length())->value()
3419 : elements->length(); 3422 : elements->length();
3420 for (int i = 0; i < length; ++i) { 3423 for (int i = 0; i < length; ++i) {
3421 Object* element = elements->get(i); 3424 Object* element = elements->get(i);
3422 if (!element->IsTheHole() && element == object) return true; 3425 if (!element->IsTheHole() && element == object) return true;
3423 } 3426 }
3424 } else { 3427 } else {
3425 Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object); 3428 Object* key = NumberDictionary::cast(elements)->SlowReverseLookup(object);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3460 case EXTERNAL_SHORT_ELEMENTS: 3463 case EXTERNAL_SHORT_ELEMENTS:
3461 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3464 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3462 case EXTERNAL_INT_ELEMENTS: 3465 case EXTERNAL_INT_ELEMENTS:
3463 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3466 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3464 case EXTERNAL_FLOAT_ELEMENTS: 3467 case EXTERNAL_FLOAT_ELEMENTS:
3465 case EXTERNAL_DOUBLE_ELEMENTS: 3468 case EXTERNAL_DOUBLE_ELEMENTS:
3466 case FAST_DOUBLE_ELEMENTS: 3469 case FAST_DOUBLE_ELEMENTS:
3467 // Raw pixels and external arrays do not reference other 3470 // Raw pixels and external arrays do not reference other
3468 // objects. 3471 // objects.
3469 break; 3472 break;
3473 case FAST_SMI_ONLY_ELEMENTS:
3474 break;
3470 case FAST_ELEMENTS: 3475 case FAST_ELEMENTS:
3471 case DICTIONARY_ELEMENTS: { 3476 case DICTIONARY_ELEMENTS: {
3472 FixedArray* elements = FixedArray::cast(this->elements()); 3477 FixedArray* elements = FixedArray::cast(this->elements());
3473 if (ReferencesObjectFromElements(elements, kind, obj)) return true; 3478 if (ReferencesObjectFromElements(elements, kind, obj)) return true;
3474 break; 3479 break;
3475 } 3480 }
3476 case NON_STRICT_ARGUMENTS_ELEMENTS: { 3481 case NON_STRICT_ARGUMENTS_ELEMENTS: {
3477 FixedArray* parameter_map = FixedArray::cast(elements()); 3482 FixedArray* parameter_map = FixedArray::cast(elements());
3478 // Check the mapped parameters. 3483 // Check the mapped parameters.
3479 int length = parameter_map->length(); 3484 int length = parameter_map->length();
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
3751 3756
3752 if (!CanSetCallback(name)) { 3757 if (!CanSetCallback(name)) {
3753 return heap->undefined_value(); 3758 return heap->undefined_value();
3754 } 3759 }
3755 3760
3756 uint32_t index = 0; 3761 uint32_t index = 0;
3757 bool is_element = name->AsArrayIndex(&index); 3762 bool is_element = name->AsArrayIndex(&index);
3758 3763
3759 if (is_element) { 3764 if (is_element) {
3760 switch (GetElementsKind()) { 3765 switch (GetElementsKind()) {
3766 case FAST_SMI_ONLY_ELEMENTS:
3761 case FAST_ELEMENTS: 3767 case FAST_ELEMENTS:
3762 case FAST_DOUBLE_ELEMENTS: 3768 case FAST_DOUBLE_ELEMENTS:
3763 break; 3769 break;
3764 case EXTERNAL_PIXEL_ELEMENTS: 3770 case EXTERNAL_PIXEL_ELEMENTS:
3765 case EXTERNAL_BYTE_ELEMENTS: 3771 case EXTERNAL_BYTE_ELEMENTS:
3766 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3772 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3767 case EXTERNAL_SHORT_ELEMENTS: 3773 case EXTERNAL_SHORT_ELEMENTS:
3768 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3774 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3769 case EXTERNAL_INT_ELEMENTS: 3775 case EXTERNAL_INT_ELEMENTS:
3770 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 3776 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
4000 } 4006 }
4001 4007
4002 uint32_t index = 0; 4008 uint32_t index = 0;
4003 bool is_element = name->AsArrayIndex(&index); 4009 bool is_element = name->AsArrayIndex(&index);
4004 4010
4005 if (is_element) { 4011 if (is_element) {
4006 if (IsJSArray()) return isolate->heap()->undefined_value(); 4012 if (IsJSArray()) return isolate->heap()->undefined_value();
4007 4013
4008 // Accessors overwrite previous callbacks (cf. with getters/setters). 4014 // Accessors overwrite previous callbacks (cf. with getters/setters).
4009 switch (GetElementsKind()) { 4015 switch (GetElementsKind()) {
4016 case FAST_SMI_ONLY_ELEMENTS:
4010 case FAST_ELEMENTS: 4017 case FAST_ELEMENTS:
4011 case FAST_DOUBLE_ELEMENTS: 4018 case FAST_DOUBLE_ELEMENTS:
4012 break; 4019 break;
4013 case EXTERNAL_PIXEL_ELEMENTS: 4020 case EXTERNAL_PIXEL_ELEMENTS:
4014 case EXTERNAL_BYTE_ELEMENTS: 4021 case EXTERNAL_BYTE_ELEMENTS:
4015 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 4022 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
4016 case EXTERNAL_SHORT_ELEMENTS: 4023 case EXTERNAL_SHORT_ELEMENTS:
4017 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 4024 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
4018 case EXTERNAL_INT_ELEMENTS: 4025 case EXTERNAL_INT_ELEMENTS:
4019 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 4026 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
(...skipping 3389 matching lines...) Expand 10 before | Expand all | Expand 10 after
7409 for (int i = 0; i < source->Capacity(); ++i) { 7416 for (int i = 0; i < source->Capacity(); ++i) {
7410 Object* key = source->KeyAt(i); 7417 Object* key = source->KeyAt(i);
7411 if (key->IsNumber()) { 7418 if (key->IsNumber()) {
7412 uint32_t entry = static_cast<uint32_t>(key->Number()); 7419 uint32_t entry = static_cast<uint32_t>(key->Number());
7413 destination->set(entry, source->ValueAt(i), mode); 7420 destination->set(entry, source->ValueAt(i), mode);
7414 } 7421 }
7415 } 7422 }
7416 } 7423 }
7417 7424
7418 7425
7419 MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity, 7426 MaybeObject* JSObject::SetFastElementsCapacityAndLength(
7420 int length) { 7427 int capacity,
7428 int length,
7429 SetFastElementsCapacityMode set_capacity_mode) {
7421 Heap* heap = GetHeap(); 7430 Heap* heap = GetHeap();
7422 // We should never end in here with a pixel or external array. 7431 // We should never end in here with a pixel or external array.
7423 ASSERT(!HasExternalArrayElements()); 7432 ASSERT(!HasExternalArrayElements());
7424 7433
7425 // Allocate a new fast elements backing store. 7434 // Allocate a new fast elements backing store.
7426 FixedArray* new_elements = NULL; 7435 FixedArray* new_elements = NULL;
7427 { Object* object; 7436 { Object* object;
7428 MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity); 7437 MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity);
7429 if (!maybe->ToObject(&object)) return maybe; 7438 if (!maybe->ToObject(&object)) return maybe;
7430 new_elements = FixedArray::cast(object); 7439 new_elements = FixedArray::cast(object);
7431 } 7440 }
7432 7441
7433 // Find the new map to use for this object if there is a map change. 7442 // Find the new map to use for this object if there is a map change.
7434 Map* new_map = NULL; 7443 Map* new_map = NULL;
7435 if (elements()->map() != heap->non_strict_arguments_elements_map()) { 7444 if (elements()->map() != heap->non_strict_arguments_elements_map()) {
7436 Object* object; 7445 Object* object;
7437 MaybeObject* maybe = GetElementsTransitionMap(FAST_ELEMENTS); 7446 bool has_fast_smi_only_elements =
7447 FLAG_smi_only_arrays &&
7448 (set_capacity_mode == kAllowSmiOnlyElements) &&
7449 (elements()->map()->has_fast_smi_only_elements() ||
7450 elements() == heap->empty_fixed_array());
7451 ElementsKind elements_kind = has_fast_smi_only_elements
7452 ? FAST_SMI_ONLY_ELEMENTS
7453 : FAST_ELEMENTS;
7454 MaybeObject* maybe = GetElementsTransitionMap(elements_kind);
7438 if (!maybe->ToObject(&object)) return maybe; 7455 if (!maybe->ToObject(&object)) return maybe;
7439 new_map = Map::cast(object); 7456 new_map = Map::cast(object);
7440 } 7457 }
7441 7458
7442 switch (GetElementsKind()) { 7459 ElementsKind elements_kind = GetElementsKind();
7460 switch (elements_kind) {
7461 case FAST_SMI_ONLY_ELEMENTS:
7443 case FAST_ELEMENTS: { 7462 case FAST_ELEMENTS: {
7444 AssertNoAllocation no_gc; 7463 AssertNoAllocation no_gc;
7445 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); 7464 WriteBarrierMode mode(new_elements->GetWriteBarrierMode(no_gc));
7446 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode); 7465 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode);
7447 set_map(new_map); 7466 set_map(new_map);
7448 set_elements(new_elements); 7467 set_elements(new_elements);
7449 break; 7468 break;
7450 } 7469 }
7451 case DICTIONARY_ELEMENTS: { 7470 case DICTIONARY_ELEMENTS: {
7452 AssertNoAllocation no_gc; 7471 AssertNoAllocation no_gc;
7453 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); 7472 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7454 CopySlowElementsToFast(NumberDictionary::cast(elements()), 7473 CopySlowElementsToFast(NumberDictionary::cast(elements()),
7455 new_elements, 7474 new_elements,
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
7538 FixedDoubleArray* elems = FixedDoubleArray::cast(obj); 7557 FixedDoubleArray* elems = FixedDoubleArray::cast(obj);
7539 7558
7540 { MaybeObject* maybe_obj = 7559 { MaybeObject* maybe_obj =
7541 GetElementsTransitionMap(FAST_DOUBLE_ELEMENTS); 7560 GetElementsTransitionMap(FAST_DOUBLE_ELEMENTS);
7542 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 7561 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7543 } 7562 }
7544 Map* new_map = Map::cast(obj); 7563 Map* new_map = Map::cast(obj);
7545 7564
7546 AssertNoAllocation no_gc; 7565 AssertNoAllocation no_gc;
7547 switch (GetElementsKind()) { 7566 switch (GetElementsKind()) {
7567 case FAST_SMI_ONLY_ELEMENTS:
7548 case FAST_ELEMENTS: { 7568 case FAST_ELEMENTS: {
7549 elems->Initialize(FixedArray::cast(elements())); 7569 elems->Initialize(FixedArray::cast(elements()));
7550 break; 7570 break;
7551 } 7571 }
7552 case FAST_DOUBLE_ELEMENTS: { 7572 case FAST_DOUBLE_ELEMENTS: {
7553 elems->Initialize(FixedDoubleArray::cast(elements())); 7573 elems->Initialize(FixedDoubleArray::cast(elements()));
7554 break; 7574 break;
7555 } 7575 }
7556 case DICTIONARY_ELEMENTS: { 7576 case DICTIONARY_ELEMENTS: {
7557 elems->Initialize(NumberDictionary::cast(elements())); 7577 elems->Initialize(NumberDictionary::cast(elements()));
(...skipping 17 matching lines...) Expand all
7575 } 7595 }
7576 7596
7577 7597
7578 MaybeObject* JSObject::SetSlowElements(Object* len) { 7598 MaybeObject* JSObject::SetSlowElements(Object* len) {
7579 // We should never end in here with a pixel or external array. 7599 // We should never end in here with a pixel or external array.
7580 ASSERT(!HasExternalArrayElements()); 7600 ASSERT(!HasExternalArrayElements());
7581 7601
7582 uint32_t new_length = static_cast<uint32_t>(len->Number()); 7602 uint32_t new_length = static_cast<uint32_t>(len->Number());
7583 7603
7584 switch (GetElementsKind()) { 7604 switch (GetElementsKind()) {
7585 case FAST_ELEMENTS: { 7605 case FAST_SMI_ONLY_ELEMENTS:
7586 case FAST_DOUBLE_ELEMENTS: 7606 case FAST_ELEMENTS:
7607 case FAST_DOUBLE_ELEMENTS: {
7587 // Make sure we never try to shrink dense arrays into sparse arrays. 7608 // Make sure we never try to shrink dense arrays into sparse arrays.
7588 ASSERT(static_cast<uint32_t>( 7609 ASSERT(static_cast<uint32_t>(
7589 FixedArrayBase::cast(elements())->length()) <= new_length); 7610 FixedArrayBase::cast(elements())->length()) <= new_length);
7590 MaybeObject* result = NormalizeElements(); 7611 MaybeObject* result = NormalizeElements();
7591 if (result->IsFailure()) return result; 7612 if (result->IsFailure()) return result;
7592 7613
7593 // Update length for JSArrays. 7614 // Update length for JSArrays.
7594 if (IsJSArray()) JSArray::cast(this)->set_length(len); 7615 if (IsJSArray()) JSArray::cast(this)->set_length(len);
7595 break; 7616 break;
7596 } 7617 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
7642 7663
7643 7664
7644 void JSArray::Expand(int required_size) { 7665 void JSArray::Expand(int required_size) {
7645 Handle<JSArray> self(this); 7666 Handle<JSArray> self(this);
7646 Handle<FixedArray> old_backing(FixedArray::cast(elements())); 7667 Handle<FixedArray> old_backing(FixedArray::cast(elements()));
7647 int old_size = old_backing->length(); 7668 int old_size = old_backing->length();
7648 int new_size = required_size > old_size ? required_size : old_size; 7669 int new_size = required_size > old_size ? required_size : old_size;
7649 Handle<FixedArray> new_backing = FACTORY->NewFixedArray(new_size); 7670 Handle<FixedArray> new_backing = FACTORY->NewFixedArray(new_size);
7650 // Can't use this any more now because we may have had a GC! 7671 // Can't use this any more now because we may have had a GC!
7651 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); 7672 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i));
7652 self->SetContent(*new_backing); 7673 GetIsolate()->factory()->SetContent(self, new_backing);
7653 } 7674 }
7654 7675
7655 7676
7656 static Failure* ArrayLengthRangeError(Heap* heap) { 7677 static Failure* ArrayLengthRangeError(Heap* heap) {
7657 HandleScope scope(heap->isolate()); 7678 HandleScope scope(heap->isolate());
7658 return heap->isolate()->Throw( 7679 return heap->isolate()->Throw(
7659 *FACTORY->NewRangeError("invalid_array_length", 7680 *FACTORY->NewRangeError("invalid_array_length",
7660 HandleVector<Object>(NULL, 0))); 7681 HandleVector<Object>(NULL, 0)));
7661 } 7682 }
7662 7683
7663 7684
7664 MaybeObject* JSObject::SetElementsLength(Object* len) { 7685 MaybeObject* JSObject::SetElementsLength(Object* len) {
7665 // We should never end in here with a pixel or external array. 7686 // We should never end in here with a pixel or external array.
7666 ASSERT(AllowsSetElementsLength()); 7687 ASSERT(AllowsSetElementsLength());
7667 7688
7668 MaybeObject* maybe_smi_length = len->ToSmi(); 7689 MaybeObject* maybe_smi_length = len->ToSmi();
7669 Object* smi_length = Smi::FromInt(0); 7690 Object* smi_length = Smi::FromInt(0);
7670 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { 7691 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) {
7671 const int value = Smi::cast(smi_length)->value(); 7692 const int value = Smi::cast(smi_length)->value();
7672 if (value < 0) return ArrayLengthRangeError(GetHeap()); 7693 if (value < 0) return ArrayLengthRangeError(GetHeap());
7673 ElementsKind elements_kind = GetElementsKind(); 7694 ElementsKind elements_kind = GetElementsKind();
7674 switch (elements_kind) { 7695 switch (elements_kind) {
7696 case FAST_SMI_ONLY_ELEMENTS:
7675 case FAST_ELEMENTS: 7697 case FAST_ELEMENTS:
7676 case FAST_DOUBLE_ELEMENTS: { 7698 case FAST_DOUBLE_ELEMENTS: {
7677 int old_capacity = FixedArrayBase::cast(elements())->length(); 7699 int old_capacity = FixedArrayBase::cast(elements())->length();
7678 if (value <= old_capacity) { 7700 if (value <= old_capacity) {
7679 if (IsJSArray()) { 7701 if (IsJSArray()) {
7680 Object* obj; 7702 Object* obj;
7681 if (elements_kind == FAST_ELEMENTS) { 7703 if (elements_kind == FAST_ELEMENTS ||
7704 elements_kind == FAST_SMI_ONLY_ELEMENTS) {
7682 MaybeObject* maybe_obj = EnsureWritableFastElements(); 7705 MaybeObject* maybe_obj = EnsureWritableFastElements();
7683 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 7706 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7684 } 7707 }
7685 if (2 * value <= old_capacity) { 7708 if (2 * value <= old_capacity) {
7686 // If more than half the elements won't be used, trim the array. 7709 // If more than half the elements won't be used, trim the array.
7687 if (value == 0) { 7710 if (value == 0) {
7688 initialize_elements(); 7711 initialize_elements();
7689 } else { 7712 } else {
7690 Address filler_start; 7713 Address filler_start;
7691 int filler_size; 7714 int filler_size;
7692 if (GetElementsKind() == FAST_ELEMENTS) { 7715 if (elements_kind == FAST_ELEMENTS ||
7716 elements_kind == FAST_SMI_ONLY_ELEMENTS) {
7693 FixedArray* fast_elements = FixedArray::cast(elements()); 7717 FixedArray* fast_elements = FixedArray::cast(elements());
7694 fast_elements->set_length(value); 7718 fast_elements->set_length(value);
7695 filler_start = fast_elements->address() + 7719 filler_start = fast_elements->address() +
7696 FixedArray::OffsetOfElementAt(value); 7720 FixedArray::OffsetOfElementAt(value);
7697 filler_size = (old_capacity - value) * kPointerSize; 7721 filler_size = (old_capacity - value) * kPointerSize;
7698 } else { 7722 } else {
7699 ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS); 7723 ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS);
7700 FixedDoubleArray* fast_double_elements = 7724 FixedDoubleArray* fast_double_elements =
7701 FixedDoubleArray::cast(elements()); 7725 FixedDoubleArray::cast(elements());
7702 fast_double_elements->set_length(value); 7726 fast_double_elements->set_length(value);
7703 filler_start = fast_double_elements->address() + 7727 filler_start = fast_double_elements->address() +
7704 FixedDoubleArray::OffsetOfElementAt(value); 7728 FixedDoubleArray::OffsetOfElementAt(value);
7705 filler_size = (old_capacity - value) * kDoubleSize; 7729 filler_size = (old_capacity - value) * kDoubleSize;
7706 } 7730 }
7707 GetHeap()->CreateFillerObjectAt(filler_start, filler_size); 7731 GetHeap()->CreateFillerObjectAt(filler_start, filler_size);
7708 } 7732 }
7709 } else { 7733 } else {
7710 // Otherwise, fill the unused tail with holes. 7734 // Otherwise, fill the unused tail with holes.
7711 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); 7735 int old_length = FastD2I(JSArray::cast(this)->length()->Number());
7712 if (GetElementsKind() == FAST_ELEMENTS) { 7736 if (elements_kind == FAST_ELEMENTS ||
7737 elements_kind == FAST_SMI_ONLY_ELEMENTS) {
7713 FixedArray* fast_elements = FixedArray::cast(elements()); 7738 FixedArray* fast_elements = FixedArray::cast(elements());
7714 for (int i = value; i < old_length; i++) { 7739 for (int i = value; i < old_length; i++) {
7715 fast_elements->set_the_hole(i); 7740 fast_elements->set_the_hole(i);
7716 } 7741 }
7717 } else { 7742 } else {
7718 ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS); 7743 ASSERT(elements_kind == FAST_DOUBLE_ELEMENTS);
7719 FixedDoubleArray* fast_double_elements = 7744 FixedDoubleArray* fast_double_elements =
7720 FixedDoubleArray::cast(elements()); 7745 FixedDoubleArray::cast(elements());
7721 for (int i = value; i < old_length; i++) { 7746 for (int i = value; i < old_length; i++) {
7722 fast_double_elements->set_the_hole(i); 7747 fast_double_elements->set_the_hole(i);
7723 } 7748 }
7724 } 7749 }
7725 } 7750 }
7726 JSArray::cast(this)->set_length(Smi::cast(smi_length)); 7751 JSArray::cast(this)->set_length(Smi::cast(smi_length));
7727 } 7752 }
7728 return this; 7753 return this;
7729 } 7754 }
7730 int min = NewElementsCapacity(old_capacity); 7755 int min = NewElementsCapacity(old_capacity);
7731 int new_capacity = value > min ? value : min; 7756 int new_capacity = value > min ? value : min;
7732 if (!ShouldConvertToSlowElements(new_capacity)) { 7757 if (!ShouldConvertToSlowElements(new_capacity)) {
7733 MaybeObject* result; 7758 MaybeObject* result;
7734 if (GetElementsKind() == FAST_ELEMENTS) { 7759 if (elements_kind == FAST_ELEMENTS ||
7735 result = SetFastElementsCapacityAndLength(new_capacity, value); 7760 elements_kind == FAST_SMI_ONLY_ELEMENTS) {
7761 SetFastElementsCapacityMode set_capacity_mode =
7762 elements_kind == FAST_SMI_ONLY_ELEMENTS
7763 ? kAllowSmiOnlyElements
7764 : kDontAllowSmiOnlyElements;
7765 result = SetFastElementsCapacityAndLength(new_capacity,
7766 value,
7767 set_capacity_mode);
7736 } else { 7768 } else {
7737 ASSERT(GetElementsKind() == FAST_DOUBLE_ELEMENTS); 7769 ASSERT(elements_kind == FAST_DOUBLE_ELEMENTS);
7738 result = SetFastDoubleElementsCapacityAndLength(new_capacity, 7770 result = SetFastDoubleElementsCapacityAndLength(new_capacity,
7739 value); 7771 value);
7740 } 7772 }
7741 if (result->IsFailure()) return result; 7773 if (result->IsFailure()) return result;
7742 return this; 7774 return this;
7743 } 7775 }
7744 break; 7776 break;
7745 } 7777 }
7746 case DICTIONARY_ELEMENTS: { 7778 case DICTIONARY_ELEMENTS: {
7747 if (IsJSArray()) { 7779 if (IsJSArray()) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
7784 if (len->ToArrayIndex(&length)) { 7816 if (len->ToArrayIndex(&length)) {
7785 return SetSlowElements(len); 7817 return SetSlowElements(len);
7786 } else { 7818 } else {
7787 return ArrayLengthRangeError(GetHeap()); 7819 return ArrayLengthRangeError(GetHeap());
7788 } 7820 }
7789 } 7821 }
7790 7822
7791 // len is not a number so make the array size one and 7823 // len is not a number so make the array size one and
7792 // set only element to len. 7824 // set only element to len.
7793 Object* obj; 7825 Object* obj;
7794 { MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(1); 7826 MaybeObject* maybe_obj = GetHeap()->AllocateFixedArray(1);
7795 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 7827 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7796 }
7797 FixedArray::cast(obj)->set(0, len); 7828 FixedArray::cast(obj)->set(0, len);
7829
7830 maybe_obj = EnsureCanContainElements(&len, 1);
7831 if (maybe_obj->IsFailure()) return maybe_obj;
7832
7798 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); 7833 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1));
7799 set_elements(FixedArray::cast(obj)); 7834 set_elements(FixedArray::cast(obj));
7800 return this; 7835 return this;
7801 } 7836 }
7802 7837
7803 7838
7804 Object* Map::GetPrototypeTransition(Object* prototype) { 7839 Object* Map::GetPrototypeTransition(Object* prototype) {
7805 FixedArray* cache = prototype_transitions(); 7840 FixedArray* cache = prototype_transitions();
7806 int number_of_transitions = NumberOfProtoTransitions(); 7841 int number_of_transitions = NumberOfProtoTransitions();
7807 const int proto_offset = 7842 const int proto_offset =
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
7935 } 7970 }
7936 ASSERT(Map::cast(new_map)->prototype() == value); 7971 ASSERT(Map::cast(new_map)->prototype() == value);
7937 real_receiver->set_map(Map::cast(new_map)); 7972 real_receiver->set_map(Map::cast(new_map));
7938 7973
7939 heap->ClearInstanceofCache(); 7974 heap->ClearInstanceofCache();
7940 ASSERT(size == Size()); 7975 ASSERT(size == Size());
7941 return value; 7976 return value;
7942 } 7977 }
7943 7978
7944 7979
7980 MaybeObject* JSObject::EnsureCanContainElements(Arguments* args,
7981 uint32_t first_arg,
7982 uint32_t arg_count) {
7983 return EnsureCanContainElements(args->arguments() - first_arg, arg_count);
7984 }
7985
7986
7945 bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) { 7987 bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) {
7946 switch (GetElementsKind()) { 7988 switch (GetElementsKind()) {
7989 case FAST_SMI_ONLY_ELEMENTS:
7947 case FAST_ELEMENTS: { 7990 case FAST_ELEMENTS: {
7948 uint32_t length = IsJSArray() ? 7991 uint32_t length = IsJSArray() ?
7949 static_cast<uint32_t> 7992 static_cast<uint32_t>
7950 (Smi::cast(JSArray::cast(this)->length())->value()) : 7993 (Smi::cast(JSArray::cast(this)->length())->value()) :
7951 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 7994 static_cast<uint32_t>(FixedArray::cast(elements())->length());
7952 if ((index < length) && 7995 if ((index < length) &&
7953 !FixedArray::cast(elements())->get(index)->IsTheHole()) { 7996 !FixedArray::cast(elements())->get(index)->IsTheHole()) {
7954 return true; 7997 return true;
7955 } 7998 }
7956 break; 7999 break;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
8078 return HasElementWithInterceptor(this, index) ? INTERCEPTED_ELEMENT 8121 return HasElementWithInterceptor(this, index) ? INTERCEPTED_ELEMENT
8079 : UNDEFINED_ELEMENT; 8122 : UNDEFINED_ELEMENT;
8080 } 8123 }
8081 8124
8082 // Handle [] on String objects. 8125 // Handle [] on String objects.
8083 if (this->IsStringObjectWithCharacterAt(index)) { 8126 if (this->IsStringObjectWithCharacterAt(index)) {
8084 return STRING_CHARACTER_ELEMENT; 8127 return STRING_CHARACTER_ELEMENT;
8085 } 8128 }
8086 8129
8087 switch (GetElementsKind()) { 8130 switch (GetElementsKind()) {
8131 case FAST_SMI_ONLY_ELEMENTS:
8088 case FAST_ELEMENTS: { 8132 case FAST_ELEMENTS: {
8089 uint32_t length = IsJSArray() ? 8133 uint32_t length = IsJSArray() ?
8090 static_cast<uint32_t> 8134 static_cast<uint32_t>
8091 (Smi::cast(JSArray::cast(this)->length())->value()) : 8135 (Smi::cast(JSArray::cast(this)->length())->value()) :
8092 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 8136 static_cast<uint32_t>(FixedArray::cast(elements())->length());
8093 if ((index < length) && 8137 if ((index < length) &&
8094 !FixedArray::cast(elements())->get(index)->IsTheHole()) { 8138 !FixedArray::cast(elements())->get(index)->IsTheHole()) {
8095 return FAST_ELEMENT; 8139 return FAST_ELEMENT;
8096 } 8140 }
8097 break; 8141 break;
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
8192 } 8236 }
8193 } 8237 }
8194 8238
8195 // Check for lookup interceptor 8239 // Check for lookup interceptor
8196 if (HasIndexedInterceptor()) { 8240 if (HasIndexedInterceptor()) {
8197 return HasElementWithInterceptor(receiver, index); 8241 return HasElementWithInterceptor(receiver, index);
8198 } 8242 }
8199 8243
8200 ElementsKind kind = GetElementsKind(); 8244 ElementsKind kind = GetElementsKind();
8201 switch (kind) { 8245 switch (kind) {
8246 case FAST_SMI_ONLY_ELEMENTS:
8202 case FAST_ELEMENTS: { 8247 case FAST_ELEMENTS: {
8203 uint32_t length = IsJSArray() ? 8248 uint32_t length = IsJSArray() ?
8204 static_cast<uint32_t> 8249 static_cast<uint32_t>
8205 (Smi::cast(JSArray::cast(this)->length())->value()) : 8250 (Smi::cast(JSArray::cast(this)->length())->value()) :
8206 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 8251 static_cast<uint32_t>(FixedArray::cast(elements())->length());
8207 if ((index < length) && 8252 if ((index < length) &&
8208 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true; 8253 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true;
8209 break; 8254 break;
8210 } 8255 }
8211 case FAST_DOUBLE_ELEMENTS: { 8256 case FAST_DOUBLE_ELEMENTS: {
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
8446 } 8491 }
8447 8492
8448 8493
8449 // Adding n elements in fast case is O(n*n). 8494 // Adding n elements in fast case is O(n*n).
8450 // Note: revisit design to have dual undefined values to capture absent 8495 // Note: revisit design to have dual undefined values to capture absent
8451 // elements. 8496 // elements.
8452 MaybeObject* JSObject::SetFastElement(uint32_t index, 8497 MaybeObject* JSObject::SetFastElement(uint32_t index,
8453 Object* value, 8498 Object* value,
8454 StrictModeFlag strict_mode, 8499 StrictModeFlag strict_mode,
8455 bool check_prototype) { 8500 bool check_prototype) {
8456 ASSERT(HasFastElements() || HasFastArgumentsElements()); 8501 ASSERT(HasFastTypeElements() ||
8502 HasFastArgumentsElements());
8457 8503
8458 FixedArray* backing_store = FixedArray::cast(elements()); 8504 FixedArray* backing_store = FixedArray::cast(elements());
8459 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) { 8505 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) {
8460 backing_store = FixedArray::cast(backing_store->get(1)); 8506 backing_store = FixedArray::cast(backing_store->get(1));
8461 } else { 8507 } else {
8462 Object* writable; 8508 Object* writable;
8463 MaybeObject* maybe = EnsureWritableFastElements(); 8509 MaybeObject* maybe = EnsureWritableFastElements();
8464 if (!maybe->ToObject(&writable)) return maybe; 8510 if (!maybe->ToObject(&writable)) return maybe;
8465 backing_store = FixedArray::cast(writable); 8511 backing_store = FixedArray::cast(writable);
8466 } 8512 }
8467 uint32_t length = static_cast<uint32_t>(backing_store->length()); 8513 uint32_t length = static_cast<uint32_t>(backing_store->length());
8468 8514
8469 if (check_prototype && 8515 if (check_prototype &&
8470 (index >= length || backing_store->get(index)->IsTheHole())) { 8516 (index >= length || backing_store->get(index)->IsTheHole())) {
8471 bool found; 8517 bool found;
8472 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, 8518 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index,
8473 value, 8519 value,
8474 &found, 8520 &found,
8475 strict_mode); 8521 strict_mode);
8476 if (found) return result; 8522 if (found) return result;
8477 } 8523 }
8478 8524
8479 // Check whether there is extra space in fixed array. 8525 // Check whether there is extra space in fixed array.
8480 if (index < length) { 8526 if (index < length) {
8527 if (HasFastSmiOnlyElements()) {
8528 if (!value->IsSmi()) {
8529 // If the value is a number, transition from smi-only to
8530 // FastDoubleElements.
8531 if (value->IsNumber()) {
8532 MaybeObject* maybe =
8533 SetFastDoubleElementsCapacityAndLength(length, length);
8534 if (maybe->IsFailure()) return maybe;
8535 FixedDoubleArray::cast(elements())->set(index, value->Number());
8536 return value;
8537 }
8538 // Value is not a number, transition to generic fast elements.
8539 MaybeObject* maybe_new_map = GetElementsTransitionMap(FAST_ELEMENTS);
8540 Map* new_map;
8541 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map;
8542 set_map(new_map);
8543 }
8544 }
8481 backing_store->set(index, value); 8545 backing_store->set(index, value);
8482 if (IsJSArray()) { 8546 if (IsJSArray()) {
8483 // Update the length of the array if needed. 8547 // Update the length of the array if needed.
8484 uint32_t array_length = 0; 8548 uint32_t array_length = 0;
8485 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); 8549 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length));
8486 if (index >= array_length) { 8550 if (index >= array_length) {
8487 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); 8551 JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
8488 } 8552 }
8489 } 8553 }
8490 return value; 8554 return value;
8491 } 8555 }
8492 8556
8493 // Allow gap in fast case. 8557 // Allow gap in fast case.
8494 if ((index - length) < kMaxGap) { 8558 if ((index - length) < kMaxGap) {
8495 // Try allocating extra space. 8559 // Try allocating extra space.
8496 int new_capacity = NewElementsCapacity(index + 1); 8560 int new_capacity = NewElementsCapacity(index + 1);
8497 if (!ShouldConvertToSlowElements(new_capacity)) { 8561 if (!ShouldConvertToSlowElements(new_capacity)) {
8498 ASSERT(static_cast<uint32_t>(new_capacity) > index); 8562 ASSERT(static_cast<uint32_t>(new_capacity) > index);
8499 Object* new_elements; 8563 Object* new_elements;
8564 SetFastElementsCapacityMode set_capacity_mode =
8565 value->IsSmi() && HasFastSmiOnlyElements()
8566 ? kAllowSmiOnlyElements
8567 : kDontAllowSmiOnlyElements;
8500 MaybeObject* maybe = 8568 MaybeObject* maybe =
8501 SetFastElementsCapacityAndLength(new_capacity, index + 1); 8569 SetFastElementsCapacityAndLength(new_capacity,
8570 index + 1,
8571 set_capacity_mode);
8502 if (!maybe->ToObject(&new_elements)) return maybe; 8572 if (!maybe->ToObject(&new_elements)) return maybe;
8503 FixedArray::cast(new_elements)->set(index, value); 8573 FixedArray::cast(new_elements)->set(index, value);
8504 return value; 8574 return value;
8505 } 8575 }
8506 } 8576 }
8507 8577
8508 // Otherwise default to slow case. 8578 // Otherwise default to slow case.
8509 MaybeObject* result = NormalizeElements(); 8579 MaybeObject* result = NormalizeElements();
8510 if (result->IsFailure()) return result; 8580 if (result->IsFailure()) return result;
8511 return SetDictionaryElement(index, value, strict_mode, check_prototype); 8581 return SetDictionaryElement(index, value, strict_mode, check_prototype);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
8597 // Attempt to put this object back in fast case. 8667 // Attempt to put this object back in fast case.
8598 if (ShouldConvertToFastElements()) { 8668 if (ShouldConvertToFastElements()) {
8599 uint32_t new_length = 0; 8669 uint32_t new_length = 0;
8600 if (IsJSArray()) { 8670 if (IsJSArray()) {
8601 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length)); 8671 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length));
8602 } else { 8672 } else {
8603 new_length = dictionary->max_number_key() + 1; 8673 new_length = dictionary->max_number_key() + 1;
8604 } 8674 }
8605 MaybeObject* result = CanConvertToFastDoubleElements() 8675 MaybeObject* result = CanConvertToFastDoubleElements()
8606 ? SetFastDoubleElementsCapacityAndLength(new_length, new_length) 8676 ? SetFastDoubleElementsCapacityAndLength(new_length, new_length)
8607 : SetFastElementsCapacityAndLength(new_length, new_length); 8677 : SetFastElementsCapacityAndLength(new_length,
8678 new_length,
8679 kDontAllowSmiOnlyElements);
8608 if (result->IsFailure()) return result; 8680 if (result->IsFailure()) return result;
8609 #ifdef DEBUG 8681 #ifdef DEBUG
8610 if (FLAG_trace_normalization) { 8682 if (FLAG_trace_normalization) {
8611 PrintF("Object elements are fast case again:\n"); 8683 PrintF("Object elements are fast case again:\n");
8612 Print(); 8684 Print();
8613 } 8685 }
8614 #endif 8686 #endif
8615 } 8687 }
8616 return value; 8688 return value;
8617 } 8689 }
(...skipping 23 matching lines...) Expand all
8641 8713
8642 // If the value object is not a heap number, switch to fast elements and try 8714 // If the value object is not a heap number, switch to fast elements and try
8643 // again. 8715 // again.
8644 bool value_is_smi = value->IsSmi(); 8716 bool value_is_smi = value->IsSmi();
8645 if (!value->IsNumber()) { 8717 if (!value->IsNumber()) {
8646 Object* obj; 8718 Object* obj;
8647 uint32_t length = elms_length; 8719 uint32_t length = elms_length;
8648 if (IsJSArray()) { 8720 if (IsJSArray()) {
8649 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); 8721 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length));
8650 } 8722 }
8651 MaybeObject* maybe_obj = 8723 MaybeObject* maybe_obj = SetFastElementsCapacityAndLength(
8652 SetFastElementsCapacityAndLength(elms_length, length); 8724 elms_length,
8725 length,
8726 kDontAllowSmiOnlyElements);
8653 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 8727 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
8654 return SetFastElement(index, value, strict_mode, check_prototype); 8728 return SetFastElement(index,
8729 value,
8730 strict_mode,
8731 check_prototype);
8655 } 8732 }
8656 8733
8657 double double_value = value_is_smi 8734 double double_value = value_is_smi
8658 ? static_cast<double>(Smi::cast(value)->value()) 8735 ? static_cast<double>(Smi::cast(value)->value())
8659 : HeapNumber::cast(value)->value(); 8736 : HeapNumber::cast(value)->value();
8660 8737
8661 // Check whether there is extra space in the fixed array. 8738 // Check whether there is extra space in the fixed array.
8662 if (index < elms_length) { 8739 if (index < elms_length) {
8663 elms->set(index, double_value); 8740 elms->set(index, double_value);
8664 if (IsJSArray()) { 8741 if (IsJSArray()) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
8752 check_prototype); 8829 check_prototype);
8753 } 8830 }
8754 8831
8755 8832
8756 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, 8833 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index,
8757 Object* value, 8834 Object* value,
8758 StrictModeFlag strict_mode, 8835 StrictModeFlag strict_mode,
8759 bool check_prototype) { 8836 bool check_prototype) {
8760 Isolate* isolate = GetIsolate(); 8837 Isolate* isolate = GetIsolate();
8761 switch (GetElementsKind()) { 8838 switch (GetElementsKind()) {
8839 case FAST_SMI_ONLY_ELEMENTS:
8762 case FAST_ELEMENTS: 8840 case FAST_ELEMENTS:
8763 return SetFastElement(index, value, strict_mode, check_prototype); 8841 return SetFastElement(index, value, strict_mode, check_prototype);
8764 case FAST_DOUBLE_ELEMENTS: 8842 case FAST_DOUBLE_ELEMENTS:
8765 return SetFastDoubleElement(index, value, strict_mode, check_prototype); 8843 return SetFastDoubleElement(index, value, strict_mode, check_prototype);
8766 case EXTERNAL_PIXEL_ELEMENTS: { 8844 case EXTERNAL_PIXEL_ELEMENTS: {
8767 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); 8845 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements());
8768 return pixels->SetValue(index, value); 8846 return pixels->SetValue(index, value);
8769 } 8847 }
8770 case EXTERNAL_BYTE_ELEMENTS: { 8848 case EXTERNAL_BYTE_ELEMENTS: {
8771 ExternalByteArray* array = ExternalByteArray::cast(elements()); 8849 ExternalByteArray* array = ExternalByteArray::cast(elements());
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
8914 backing_store_base = 8992 backing_store_base =
8915 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); 8993 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1));
8916 backing_store = FixedArray::cast(backing_store_base); 8994 backing_store = FixedArray::cast(backing_store_base);
8917 if (backing_store->IsDictionary()) { 8995 if (backing_store->IsDictionary()) {
8918 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); 8996 NumberDictionary* dictionary = NumberDictionary::cast(backing_store);
8919 *capacity = dictionary->Capacity(); 8997 *capacity = dictionary->Capacity();
8920 *used = dictionary->NumberOfElements(); 8998 *used = dictionary->NumberOfElements();
8921 break; 8999 break;
8922 } 9000 }
8923 // Fall through. 9001 // Fall through.
9002 case FAST_SMI_ONLY_ELEMENTS:
8924 case FAST_ELEMENTS: 9003 case FAST_ELEMENTS:
8925 backing_store = FixedArray::cast(backing_store_base); 9004 backing_store = FixedArray::cast(backing_store_base);
8926 *capacity = backing_store->length(); 9005 *capacity = backing_store->length();
8927 for (int i = 0; i < *capacity; ++i) { 9006 for (int i = 0; i < *capacity; ++i) {
8928 if (!backing_store->get(i)->IsTheHole()) ++(*used); 9007 if (!backing_store->get(i)->IsTheHole()) ++(*used);
8929 } 9008 }
8930 break; 9009 break;
8931 case DICTIONARY_ELEMENTS: { 9010 case DICTIONARY_ELEMENTS: {
8932 NumberDictionary* dictionary = 9011 NumberDictionary* dictionary =
8933 NumberDictionary::cast(FixedArray::cast(elements())); 9012 NumberDictionary::cast(FixedArray::cast(elements()));
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
9189 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { 9268 if (!heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) {
9190 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); 9269 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS);
9191 return false; 9270 return false;
9192 } 9271 }
9193 } 9272 }
9194 9273
9195 // Handle [] on String objects. 9274 // Handle [] on String objects.
9196 if (this->IsStringObjectWithCharacterAt(index)) return true; 9275 if (this->IsStringObjectWithCharacterAt(index)) return true;
9197 9276
9198 switch (GetElementsKind()) { 9277 switch (GetElementsKind()) {
9278 case FAST_SMI_ONLY_ELEMENTS:
9199 case FAST_ELEMENTS: { 9279 case FAST_ELEMENTS: {
9200 uint32_t length = IsJSArray() ? 9280 uint32_t length = IsJSArray() ?
9201 static_cast<uint32_t>( 9281 static_cast<uint32_t>(
9202 Smi::cast(JSArray::cast(this)->length())->value()) : 9282 Smi::cast(JSArray::cast(this)->length())->value()) :
9203 static_cast<uint32_t>(FixedArray::cast(elements())->length()); 9283 static_cast<uint32_t>(FixedArray::cast(elements())->length());
9204 return (index < length) && 9284 return (index < length) &&
9205 !FixedArray::cast(elements())->get(index)->IsTheHole(); 9285 !FixedArray::cast(elements())->get(index)->IsTheHole();
9206 } 9286 }
9207 case FAST_DOUBLE_ELEMENTS: { 9287 case FAST_DOUBLE_ELEMENTS: {
9208 uint32_t length = IsJSArray() ? 9288 uint32_t length = IsJSArray() ?
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
9428 } 9508 }
9429 // Compute the number of enumerable elements. 9509 // Compute the number of enumerable elements.
9430 return NumberOfLocalElements(static_cast<PropertyAttributes>(DONT_ENUM)); 9510 return NumberOfLocalElements(static_cast<PropertyAttributes>(DONT_ENUM));
9431 } 9511 }
9432 9512
9433 9513
9434 int JSObject::GetLocalElementKeys(FixedArray* storage, 9514 int JSObject::GetLocalElementKeys(FixedArray* storage,
9435 PropertyAttributes filter) { 9515 PropertyAttributes filter) {
9436 int counter = 0; 9516 int counter = 0;
9437 switch (GetElementsKind()) { 9517 switch (GetElementsKind()) {
9518 case FAST_SMI_ONLY_ELEMENTS:
9438 case FAST_ELEMENTS: { 9519 case FAST_ELEMENTS: {
9439 int length = IsJSArray() ? 9520 int length = IsJSArray() ?
9440 Smi::cast(JSArray::cast(this)->length())->value() : 9521 Smi::cast(JSArray::cast(this)->length())->value() :
9441 FixedArray::cast(elements())->length(); 9522 FixedArray::cast(elements())->length();
9442 for (int i = 0; i < length; i++) { 9523 for (int i = 0; i < length; i++) {
9443 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { 9524 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) {
9444 if (storage != NULL) { 9525 if (storage != NULL) {
9445 storage->set(counter, Smi::FromInt(i)); 9526 storage->set(counter, Smi::FromInt(i));
9446 } 9527 }
9447 counter++; 9528 counter++;
(...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after
10330 dict->CopyValuesTo(fast_elements); 10411 dict->CopyValuesTo(fast_elements);
10331 10412
10332 set_map(new_map); 10413 set_map(new_map);
10333 set_elements(fast_elements); 10414 set_elements(fast_elements);
10334 } else if (!HasFastDoubleElements()) { 10415 } else if (!HasFastDoubleElements()) {
10335 Object* obj; 10416 Object* obj;
10336 { MaybeObject* maybe_obj = EnsureWritableFastElements(); 10417 { MaybeObject* maybe_obj = EnsureWritableFastElements();
10337 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 10418 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
10338 } 10419 }
10339 } 10420 }
10340 ASSERT(HasFastElements() || HasFastDoubleElements()); 10421 ASSERT(HasFastTypeElements() ||
10422 HasFastDoubleElements());
10341 10423
10342 // Collect holes at the end, undefined before that and the rest at the 10424 // Collect holes at the end, undefined before that and the rest at the
10343 // start, and return the number of non-hole, non-undefined values. 10425 // start, and return the number of non-hole, non-undefined values.
10344 10426
10345 FixedArrayBase* elements_base = FixedArrayBase::cast(this->elements()); 10427 FixedArrayBase* elements_base = FixedArrayBase::cast(this->elements());
10346 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); 10428 uint32_t elements_length = static_cast<uint32_t>(elements_base->length());
10347 if (limit > elements_length) { 10429 if (limit > elements_length) {
10348 limit = elements_length ; 10430 limit = elements_length ;
10349 } 10431 }
10350 if (limit == 0) { 10432 if (limit == 0) {
(...skipping 1414 matching lines...) Expand 10 before | Expand all | Expand 10 after
11765 if (break_point_objects()->IsUndefined()) return 0; 11847 if (break_point_objects()->IsUndefined()) return 0;
11766 // Single break point. 11848 // Single break point.
11767 if (!break_point_objects()->IsFixedArray()) return 1; 11849 if (!break_point_objects()->IsFixedArray()) return 1;
11768 // Multiple break points. 11850 // Multiple break points.
11769 return FixedArray::cast(break_point_objects())->length(); 11851 return FixedArray::cast(break_point_objects())->length();
11770 } 11852 }
11771 #endif 11853 #endif
11772 11854
11773 11855
11774 } } // namespace v8::internal 11856 } } // namespace v8::internal
OLDNEW
« src/bootstrapper.cc ('K') | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698