Handle<JSObject> holder = GetHolder<JSObject>();
if (IsElement()) {
- ElementsKind old_kind = holder_map_->elements_kind();
- holder_map_ = Map::PrepareForDataElement(holder_map_, value);
- ElementsKind new_kind = holder_map_->elements_kind();
- if (new_kind != old_kind) {
- // TODO(verwaest): Handle element migration in MigrateToMap.
- JSObject::UpdateAllocationSite(holder, new_kind);
- if (IsFastDoubleElementsKind(old_kind) !=
- IsFastDoubleElementsKind(new_kind)) {
- uint32_t capacity = holder->elements()->length();
- ElementsAccessor* accessor = ElementsAccessor::ForKind(new_kind);
- accessor->GrowCapacityAndConvert(holder, capacity);
- // GrowCapacityAndConvert migrated the object. No reloading of property
- // infomation is necessary for elements.
- return;
- } else if (FLAG_trace_elements_transitions) {
- Handle<FixedArrayBase> elements(holder->elements());
- JSObject::PrintElementsTransition(stdout, holder, old_kind, elements,
- new_kind, elements);
- }
- }
+ ElementsKind kind = holder_map_->elements_kind();
+ ElementsKind to = value->OptimalElementsKind();
+ if (IsHoleyElementsKind(kind)) to = GetHoleyElementsKind(to);
+ to = IsMoreGeneralElementsKindTransition(kind, to) ? to : kind;
+ JSObject::TransitionElementsKind(holder, to);
+ holder_map_ = handle(holder->map(), isolate_);
// Copy the backing store if it is copy-on-write.
- if (IsFastSmiOrObjectElementsKind(new_kind)) {
+ if (IsFastSmiOrObjectElementsKind(to)) {
JSObject::EnsureWritableFastElements(holder);
}
bool Object::IsJSObject() const {
STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
- return IsHeapObject() &&
- HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
+ return IsHeapObject() && HeapObject::cast(this)->map()->IsJSObjectMap();
}
// static
-Handle<Map> Map::PrepareForDataElement(Handle<Map> map, Handle<Object> value) {
- ElementsKind kind = map->elements_kind();
- bool holey = IsHoleyElementsKind(kind);
-
- switch (kind) {
- case FAST_SMI_ELEMENTS:
- case FAST_HOLEY_SMI_ELEMENTS:
- if (value->IsSmi()) return map;
- kind = value->IsNumber() ? FAST_DOUBLE_ELEMENTS : FAST_ELEMENTS;
- break;
-
- case FAST_DOUBLE_ELEMENTS:
- case FAST_HOLEY_DOUBLE_ELEMENTS:
- if (value->IsNumber()) return map;
- kind = FAST_ELEMENTS;
- break;
-
- case FAST_ELEMENTS:
- case FAST_HOLEY_ELEMENTS:
- case DICTIONARY_ELEMENTS:
- case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
- case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
-#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
- case EXTERNAL_##TYPE##_ELEMENTS: \
- case TYPE##_ELEMENTS:
-
- TYPED_ARRAYS(TYPED_ARRAY_CASE)
-#undef TYPED_ARRAY_CASE
- return map;
- }
-
- if (holey) kind = GetHoleyElementsKind(kind);
- return Map::AsElementsKind(map, kind);
-}
-
-
-// static
Handle<Map> Map::PrepareForDataProperty(Handle<Map> map, int descriptor,
Handle<Object> value) {
// Dictionaries can store any property value.
static Handle<Map> PrepareForDataProperty(Handle<Map> old_map,
int descriptor_number,
Handle<Object> value);
- static Handle<Map> PrepareForDataElement(Handle<Map> old_map,
- Handle<Object> value);
static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode,
const char* reason);
bool IsJSObjectMap() {
return instance_type() >= FIRST_JS_OBJECT_TYPE;
}
+ bool IsJSArrayMap() { return instance_type() == JS_ARRAY_TYPE; }
bool IsStringMap() { return instance_type() < FIRST_NONSTRING_TYPE; }
bool IsJSProxyMap() {
InstanceType type = instance_type();