summaryrefslogtreecommitdiffstats
path: root/src/objects.cc
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-07-08 12:39:36 +0100
committerSteve Block <steveblock@google.com>2010-07-08 12:41:04 +0100
commit8defd9ff6930b4e24729971a61cf7469daf119be (patch)
tree3be589af44201dcaead530f4046cb63e7c9b68c4 /src/objects.cc
parent85dec77e821ae98054f8e09ba3180c148a9264d6 (diff)
downloadandroid_external_v8-8defd9ff6930b4e24729971a61cf7469daf119be.tar.gz
android_external_v8-8defd9ff6930b4e24729971a61cf7469daf119be.tar.bz2
android_external_v8-8defd9ff6930b4e24729971a61cf7469daf119be.zip
Update V8 to r5017 as required by WebKit r62496
Change-Id: I1b4b7718d1d77ceef07f543e9150a2cb3a628f3a
Diffstat (limited to 'src/objects.cc')
-rw-r--r--src/objects.cc110
1 files changed, 78 insertions, 32 deletions
diff --git a/src/objects.cc b/src/objects.cc
index 63b77b79..8288f636 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -678,7 +678,7 @@ Object* String::SlowTryFlatten(PretenureFlag pretenure) {
bool String::MakeExternal(v8::String::ExternalStringResource* resource) {
- // Externalizing twice leaks the external resouce, so it's
+ // Externalizing twice leaks the external resource, so it's
// prohibited by the API.
ASSERT(!this->IsExternalString());
#ifdef DEBUG
@@ -1276,7 +1276,7 @@ Object* JSObject::AddFastProperty(String* name,
}
if (map()->unused_property_fields() == 0) {
- if (properties()->length() > kMaxFastProperties) {
+ if (properties()->length() > MaxFastProperties()) {
Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
if (obj->IsFailure()) return obj;
return AddSlowProperty(name, value, attributes);
@@ -1386,6 +1386,11 @@ Object* JSObject::AddProperty(String* name,
Object* value,
PropertyAttributes attributes) {
ASSERT(!IsJSGlobalProxy());
+ if (!map()->is_extensible()) {
+ Handle<Object> args[1] = {Handle<String>(name)};
+ return Top::Throw(*Factory::NewTypeError("object_not_extensible",
+ HandleVector(args, 1)));
+ }
if (HasFastProperties()) {
// Ensure the descriptor array does not get too big.
if (map()->instance_descriptors()->number_of_descriptors() <
@@ -1474,7 +1479,7 @@ Object* JSObject::ConvertDescriptorToField(String* name,
Object* new_value,
PropertyAttributes attributes) {
if (map()->unused_property_fields() == 0 &&
- properties()->length() > kMaxFastProperties) {
+ properties()->length() > MaxFastProperties()) {
Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
if (obj->IsFailure()) return obj;
return ReplaceSlowProperty(name, new_value, attributes);
@@ -1746,8 +1751,6 @@ void JSObject::LocalLookupRealNamedProperty(String* name,
result->DictionaryResult(this, entry);
return;
}
- // Slow case object skipped during lookup. Do not use inline caching.
- if (!IsGlobalObject()) result->DisallowCaching();
}
result->NotFound();
}
@@ -2222,6 +2225,11 @@ Object* JSObject::TransformToFastProperties(int unused_property_fields) {
Object* JSObject::NormalizeElements() {
ASSERT(!HasPixelElements() && !HasExternalArrayElements());
if (HasDictionaryElements()) return this;
+ ASSERT(map()->has_fast_elements());
+
+ Object* obj = map()->GetSlowElementsMap();
+ if (obj->IsFailure()) return obj;
+ Map* new_map = Map::cast(obj);
// Get number of entries.
FixedArray* array = FixedArray::cast(elements());
@@ -2230,7 +2238,7 @@ Object* JSObject::NormalizeElements() {
int length = IsJSArray() ?
Smi::cast(JSArray::cast(this)->length())->value() :
array->length();
- Object* obj = NumberDictionary::Allocate(length);
+ obj = NumberDictionary::Allocate(length);
if (obj->IsFailure()) return obj;
NumberDictionary* dictionary = NumberDictionary::cast(obj);
// Copy entries.
@@ -2243,7 +2251,10 @@ Object* JSObject::NormalizeElements() {
dictionary = NumberDictionary::cast(result);
}
}
- // Switch to using the dictionary as the backing storage for elements.
+ // Switch to using the dictionary as the backing storage for
+ // elements. Set the new map first to satify the elements type
+ // assert in set_elements().
+ set_map(new_map);
set_elements(dictionary);
Counters::elements_to_dictionary.Increment();
@@ -2568,6 +2579,25 @@ bool JSObject::ReferencesObject(Object* obj) {
}
+Object* JSObject::PreventExtensions() {
+ // If there are fast elements we normalize.
+ if (HasFastElements()) {
+ NormalizeElements();
+ }
+ // Make sure that we never go back to fast case.
+ element_dictionary()->set_requires_slow_elements();
+
+ // Do a map transition, other objects with this map may still
+ // be extensible.
+ Object* new_map = map()->CopyDropTransitions();
+ if (new_map->IsFailure()) return new_map;
+ Map::cast(new_map)->set_is_extensible(false);
+ set_map(Map::cast(new_map));
+ ASSERT(!map()->is_extensible());
+ return new_map;
+}
+
+
// Tests for the fast common case for property enumeration:
// - This object and all prototypes has an enum cache (which means that it has
// no interceptors and needs no access checks).
@@ -3068,7 +3098,7 @@ Object* Map::CopyDropTransitions() {
Object* descriptors = instance_descriptors()->RemoveTransitions();
if (descriptors->IsFailure()) return descriptors;
cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors));
- return cast(new_map);
+ return new_map;
}
@@ -5473,14 +5503,18 @@ void Code::Disassemble(const char* name) {
#endif // ENABLE_DISASSEMBLER
-void JSObject::SetFastElements(FixedArray* elems) {
+Object* JSObject::SetFastElementsCapacityAndLength(int capacity, int length) {
// We should never end in here with a pixel or external array.
ASSERT(!HasPixelElements() && !HasExternalArrayElements());
-#ifdef DEBUG
- // Check the provided array is filled with the_hole.
- uint32_t len = static_cast<uint32_t>(elems->length());
- for (uint32_t i = 0; i < len; i++) ASSERT(elems->get(i)->IsTheHole());
-#endif
+
+ Object* obj = Heap::AllocateFixedArrayWithHoles(capacity);
+ if (obj->IsFailure()) return obj;
+ FixedArray* elems = FixedArray::cast(obj);
+
+ obj = map()->GetFastElementsMap();
+ if (obj->IsFailure()) return obj;
+ Map* new_map = Map::cast(obj);
+
AssertNoAllocation no_gc;
WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc);
switch (GetElementsKind()) {
@@ -5508,7 +5542,15 @@ void JSObject::SetFastElements(FixedArray* elems) {
UNREACHABLE();
break;
}
+
+ set_map(new_map);
set_elements(elems);
+
+ if (IsJSArray()) {
+ JSArray::cast(this)->set_length(Smi::FromInt(length));
+ }
+
+ return this;
}
@@ -5595,7 +5637,7 @@ Object* JSObject::SetElementsLength(Object* len) {
Object* smi_length = len->ToSmi();
if (smi_length->IsSmi()) {
- int value = Smi::cast(smi_length)->value();
+ const int value = Smi::cast(smi_length)->value();
if (value < 0) return ArrayLengthRangeError();
switch (GetElementsKind()) {
case FAST_ELEMENTS: {
@@ -5617,12 +5659,8 @@ Object* JSObject::SetElementsLength(Object* len) {
int new_capacity = value > min ? value : min;
if (new_capacity <= kMaxFastElementsLength ||
!ShouldConvertToSlowElements(new_capacity)) {
- Object* obj = Heap::AllocateFixedArrayWithHoles(new_capacity);
+ Object* obj = SetFastElementsCapacityAndLength(new_capacity, value);
if (obj->IsFailure()) return obj;
- if (IsJSArray()) {
- JSArray::cast(this)->set_length(Smi::cast(smi_length));
- }
- SetFastElements(FixedArray::cast(obj));
return this;
}
break;
@@ -5633,7 +5671,8 @@ Object* JSObject::SetElementsLength(Object* len) {
// If the length of a slow array is reset to zero, we clear
// the array and flush backing storage. This has the added
// benefit that the array returns to fast mode.
- initialize_elements();
+ Object* obj = ResetElements();
+ if (obj->IsFailure()) return obj;
} else {
// Remove deleted elements.
uint32_t old_length =
@@ -6092,12 +6131,8 @@ Object* JSObject::SetFastElement(uint32_t index, Object* value) {
if (new_capacity <= kMaxFastElementsLength ||
!ShouldConvertToSlowElements(new_capacity)) {
ASSERT(static_cast<uint32_t>(new_capacity) > index);
- Object* obj = Heap::AllocateFixedArrayWithHoles(new_capacity);
+ Object* obj = SetFastElementsCapacityAndLength(new_capacity, index + 1);
if (obj->IsFailure()) return obj;
- SetFastElements(FixedArray::cast(obj));
- if (IsJSArray()) {
- JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
- }
FixedArray::cast(elements())->set(index, value);
return value;
}
@@ -6196,6 +6231,15 @@ Object* JSObject::SetElementWithoutInterceptor(uint32_t index, Object* value) {
return value;
}
}
+ // When we set the is_extensible flag to false we always force
+ // the element into dictionary mode (and force them to stay there).
+ if (!map()->is_extensible()) {
+ Handle<Object> number(Heap::NumberFromUint32(index));
+ Handle<String> index_string(Factory::NumberToString(number));
+ Handle<Object> args[1] = { index_string };
+ return Top::Throw(*Factory::NewTypeError("object_not_extensible",
+ HandleVector(args, 1)));
+ }
Object* result = dictionary->AtNumberPut(index, value);
if (result->IsFailure()) return result;
if (elms != FixedArray::cast(result)) {
@@ -6216,13 +6260,11 @@ Object* JSObject::SetElementWithoutInterceptor(uint32_t index, Object* value) {
uint32_t new_length = 0;
if (IsJSArray()) {
CHECK(JSArray::cast(this)->length()->ToArrayIndex(&new_length));
- JSArray::cast(this)->set_length(Smi::FromInt(new_length));
} else {
new_length = NumberDictionary::cast(elements())->max_number_key() + 1;
}
- Object* obj = Heap::AllocateFixedArrayWithHoles(new_length);
+ Object* obj = SetFastElementsCapacityAndLength(new_length, new_length);
if (obj->IsFailure()) return obj;
- SetFastElements(FixedArray::cast(obj));
#ifdef DEBUG
if (FLAG_trace_normalization) {
PrintF("Object elements are fast case again:\n");
@@ -7526,14 +7568,18 @@ Object* JSObject::PrepareElementsForSort(uint32_t limit) {
}
// Convert to fast elements.
+ Object* obj = map()->GetFastElementsMap();
+ if (obj->IsFailure()) return obj;
+ Map* new_map = Map::cast(obj);
+
PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED: TENURED;
Object* new_array =
Heap::AllocateFixedArray(dict->NumberOfElements(), tenure);
- if (new_array->IsFailure()) {
- return new_array;
- }
+ if (new_array->IsFailure()) return new_array;
FixedArray* fast_elements = FixedArray::cast(new_array);
dict->CopyValuesTo(fast_elements);
+
+ set_map(new_map);
set_elements(fast_elements);
}
ASSERT(HasFastElements());