SLOW_ASSERT(transitions()->IsSortedNoDuplicates());
SLOW_ASSERT(transitions()->IsConsistentWithBackPointers(this));
}
+ ASSERT(!is_observed() || instance_type() < FIRST_JS_OBJECT_TYPE ||
+ instance_type() > LAST_JS_OBJECT_TYPE ||
+ has_slow_elements_kind() || has_external_array_elements());
}
MaybeObject* JSObject::ResetElements() {
- Object* obj;
+ if (map()->is_observed()) {
+ // Maintain invariant that observed elements are always in dictionary mode.
+ SeededNumberDictionary* dictionary;
+ MaybeObject* maybe = SeededNumberDictionary::Allocate(0);
+ if (!maybe->To(&dictionary)) return maybe;
+ if (map() == GetHeap()->non_strict_arguments_elements_map()) {
+ FixedArray::cast(elements())->set(1, dictionary);
+ } else {
+ set_elements(dictionary);
+ }
+ return this;
+ }
+
ElementsKind elements_kind = GetInitialFastElementsKind();
if (!FLAG_smi_only_arrays) {
elements_kind = FastSmiToObjectElementsKind(elements_kind);
}
- MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
- elements_kind);
- if (!maybe_obj->ToObject(&obj)) return maybe_obj;
- set_map(Map::cast(obj));
+ MaybeObject* maybe = GetElementsTransitionMap(GetIsolate(), elements_kind);
+ Map* map;
+ if (!maybe->To(&map)) return maybe;
+ set_map(map);
initialize_elements();
- if (FLAG_harmony_observation && map()->is_observed()) {
- // Maintain invariant that observed elements are always in dictionary mode.
- // For this to work on arrays, we have to make sure to reset length first.
- if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(0));
- maybe_obj = NormalizeElements();
- if (maybe_obj->IsFailure()) return maybe_obj;
- }
+
return this;
}
void Map::set_is_observed(bool is_observed) {
+ ASSERT(instance_type() < FIRST_JS_OBJECT_TYPE ||
+ instance_type() > LAST_JS_OBJECT_TYPE ||
+ has_slow_elements_kind() || has_external_array_elements());
set_bit_field3(IsObserved::update(bit_field3(), is_observed));
}
inline void set_elements_kind(ElementsKind elements_kind) {
ASSERT(elements_kind < kElementsKindCount);
ASSERT(kElementsKindCount <= (1 << kElementsKindBitCount));
+ ASSERT(!is_observed() ||
+ elements_kind == DICTIONARY_ELEMENTS ||
+ elements_kind == NON_STRICT_ARGUMENTS_ELEMENTS ||
+ IsExternalArrayElementsKind(elements_kind));
set_bit_field2((bit_field2() & ~kElementsKindMask) |
(elements_kind << kElementsKindShift));
ASSERT(this->elements_kind() == elements_kind);
Handle<Object> object = args.at<Object>(0);
if (object->IsJSObject()) {
Handle<JSObject> js_object(Handle<JSObject>::cast(object));
+ ASSERT(!js_object->map()->is_observed());
ElementsKind new_kind = js_object->HasFastHoleyElements()
? FAST_HOLEY_DOUBLE_ELEMENTS
: FAST_DOUBLE_ELEMENTS;
Handle<Object> object = args.at<Object>(0);
if (object->IsJSObject()) {
Handle<JSObject> js_object(Handle<JSObject>::cast(object));
+ ASSERT(!js_object->map()->is_observed());
ElementsKind new_kind = js_object->HasFastHoleyElements()
? FAST_HOLEY_ELEMENTS
: FAST_ELEMENTS;
ASSERT(proto->IsJSGlobalObject());
obj = JSReceiver::cast(proto);
}
+ ASSERT(!(obj->map()->is_observed() && obj->IsJSObject() &&
+ JSObject::cast(obj)->HasFastElements()));
if (obj->map()->is_observed() != is_observed) {
- MaybeObject* maybe = obj->map()->Copy();
- Map* map;
- if (!maybe->To(&map)) return maybe;
- map->set_is_observed(is_observed);
- obj->set_map(map);
if (is_observed && obj->IsJSObject() &&
!JSObject::cast(obj)->HasExternalArrayElements()) {
// Go to dictionary mode, so that we don't skip map checks.
- maybe = JSObject::cast(obj)->NormalizeElements();
+ MaybeObject* maybe = JSObject::cast(obj)->NormalizeElements();
if (maybe->IsFailure()) return maybe;
ASSERT(!JSObject::cast(obj)->HasFastElements());
}
+ MaybeObject* maybe = obj->map()->Copy();
+ Map* map;
+ if (!maybe->To(&map)) return maybe;
+ map->set_is_observed(is_observed);
+ obj->set_map(map);
}
return isolate->heap()->undefined_value();
}
}
}
-// TODO(rossberg): Still flaky on buildbots, disable for now...
-/*
for (var b1 = 0; b1 < 2; ++b1)
for (var b2 = 0; b2 < 2; ++b2)
for (var n1 = 0; n1 < 3; ++n1)
for (var n2 = 0; n2 < 3; ++n2)
TestFastElementsLength(b1 != 0, b2 != 0, 20*n1, 20*n2);
-*/