Commit 046e91dd authored by verwaest's avatar verwaest Committed by Commit bot

Move SetFastElementsCapacity into GrowCapacityAndConvert

BUG=v8:4137
LOG=n

Review URL: https://codereview.chromium.org/1197133003

Cr-Commit-Position: refs/heads/master@{#29222}
parent 22b691ba
......@@ -544,6 +544,7 @@ void ArrayLiteral::BuildConstantElements(Isolate* isolate) {
if (array_index != values()->length()) {
JSArray::SetLength(array, array_index);
}
JSObject::ValidateElements(array);
Handle<FixedArrayBase> element_values(array->elements());
// Simple and shallow arrays can be lazily copied, we transform the
......
......@@ -556,7 +556,7 @@ class ElementsAccessorBase : public ElementsAccessor {
typedef ElementsTraitsParam ElementsTraits;
typedef typename ElementsTraitsParam::BackingStore BackingStore;
ElementsKind kind() const final { return ElementsTraits::Kind; }
static ElementsKind kind() { return ElementsTraits::Kind; }
static void ValidateContents(Handle<JSObject> holder, int length) {
}
......@@ -644,9 +644,59 @@ class ElementsAccessorBase : public ElementsAccessor {
static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
Handle<FixedArrayBase> backing_store);
static void GrowCapacityAndConvertImpl(Handle<JSObject> obj,
static Handle<FixedArrayBase> ConvertElementsWithCapacity(
Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
ElementsKind from_kind, uint32_t capacity) {
Isolate* isolate = object->GetIsolate();
Handle<FixedArrayBase> elements;
if (IsFastDoubleElementsKind(kind())) {
elements = isolate->factory()->NewFixedDoubleArray(capacity);
} else {
elements = isolate->factory()->NewUninitializedFixedArray(capacity);
}
int packed = kPackedSizeNotKnown;
if (IsFastPackedElementsKind(from_kind) && object->IsJSArray()) {
packed = Smi::cast(JSArray::cast(*object)->length())->value();
}
ElementsAccessorSubclass::CopyElementsImpl(
*old_elements, 0, *elements, from_kind, 0, packed,
ElementsAccessor::kCopyToEndAndInitializeToHole);
return elements;
}
static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
uint32_t capacity) {
UNIMPLEMENTED();
ElementsKind from_kind = object->GetElementsKind();
if (IsFastSmiOrObjectElementsKind(from_kind)) {
// Array optimizations rely on the prototype lookups of Array objects
// always returning undefined. If there is a store to the initial
// prototype object, make sure all of these optimizations are invalidated.
object->GetIsolate()->UpdateArrayProtectorOnSetLength(object);
}
Handle<FixedArrayBase> old_elements(object->elements());
// This method should only be called if there's a reason to update the
// elements.
DCHECK(IsFastDoubleElementsKind(from_kind) !=
IsFastDoubleElementsKind(kind()) ||
IsDictionaryElementsKind(from_kind) ||
static_cast<uint32_t>(old_elements->length()) < capacity);
Handle<FixedArrayBase> elements =
ConvertElementsWithCapacity(object, old_elements, from_kind, capacity);
ElementsKind to_kind = kind();
if (IsHoleyElementsKind(from_kind)) to_kind = GetHoleyElementsKind(to_kind);
Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, to_kind);
JSObject::SetMapAndElements(object, new_map, elements);
// Transition through the allocation site as well if present.
JSObject::UpdateAllocationSite(object, to_kind);
if (FLAG_trace_elements_transitions) {
JSObject::PrintElementsTransition(stdout, object, from_kind, old_elements,
to_kind, elements);
}
}
virtual void GrowCapacityAndConvert(Handle<JSObject> object,
......@@ -1035,16 +1085,6 @@ class FastSmiOrObjectElementsAccessor
#undef TYPED_ARRAY_CASE
}
}
static void GrowCapacityAndConvertImpl(Handle<JSObject> obj,
uint32_t capacity) {
JSObject::SetFastElementsCapacitySmiMode set_capacity_mode =
obj->HasFastSmiElements()
? JSObject::kAllowSmiElements
: JSObject::kDontAllowSmiElements;
JSObject::SetFastElementsCapacity(obj, capacity, set_capacity_mode);
}
};
......@@ -1105,34 +1145,6 @@ class FastDoubleElementsAccessor
: FastElementsAccessor<FastElementsAccessorSubclass,
KindTraits>(name) {}
static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
uint32_t capacity) {
Handle<FixedArrayBase> elements =
object->GetIsolate()->factory()->NewFixedDoubleArray(capacity);
ElementsKind from_kind = object->GetElementsKind();
ElementsKind to_kind = IsHoleyElementsKind(from_kind)
? FAST_HOLEY_DOUBLE_ELEMENTS
: FAST_DOUBLE_ELEMENTS;
Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, to_kind);
Handle<FixedArrayBase> old_elements(object->elements());
int packed = kPackedSizeNotKnown;
if (IsFastPackedElementsKind(from_kind) && object->IsJSArray()) {
packed = Smi::cast(JSArray::cast(*object)->length())->value();
}
CopyElementsImpl(*old_elements, 0, *elements, from_kind, 0, packed,
ElementsAccessor::kCopyToEndAndInitializeToHole);
JSObject::SetMapAndElements(object, new_map, elements);
JSObject::ValidateElements(object);
if (FLAG_trace_elements_transitions) {
JSObject::PrintElementsTransition(stdout, object, from_kind, old_elements,
to_kind, elements);
}
}
protected:
static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
FixedArrayBase* to, ElementsKind from_kind,
......@@ -1494,6 +1506,22 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
}
}
static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
uint32_t capacity) {
Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
Handle<FixedArray> old_elements(FixedArray::cast(parameter_map->get(1)));
ElementsKind from_kind = old_elements->IsDictionary() ? DICTIONARY_ELEMENTS
: FAST_HOLEY_ELEMENTS;
// This method should only be called if there's a reason to update the
// elements.
DCHECK(IsDictionaryElementsKind(from_kind) ||
static_cast<uint32_t>(old_elements->length()) < capacity);
Handle<FixedArrayBase> elements =
ConvertElementsWithCapacity(object, old_elements, from_kind, capacity);
parameter_map->set(1, *elements);
JSObject::ValidateElements(object);
}
static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) {
FixedArray* parameter_map = FixedArray::cast(store);
Object* probe = GetParameterMapArg(parameter_map, key);
......@@ -1556,7 +1584,15 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
FixedArrayBase* to, ElementsKind from_kind,
uint32_t to_start, int packed_size,
int copy_size) {
UNREACHABLE();
DCHECK(!to->IsDictionary());
if (from_kind == DICTIONARY_ELEMENTS) {
CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS,
to_start, copy_size);
} else {
DCHECK_EQ(FAST_HOLEY_ELEMENTS, from_kind);
CopyObjectToObjectElements(from, from_kind, from_start, to,
FAST_HOLEY_ELEMENTS, to_start, copy_size);
}
}
static uint32_t GetCapacityImpl(JSObject* holder,
......
......@@ -20,7 +20,6 @@ class ElementsAccessor {
explicit ElementsAccessor(const char* name) : name_(name) { }
virtual ~ElementsAccessor() { }
virtual ElementsKind kind() const = 0;
const char* name() const { return name_; }
// Checks the elements of an object for consistency, asserting when a problem
......
This diff is collapsed.
......@@ -2025,10 +2025,7 @@ class JSObject: public JSReceiver {
// storage would. In that case the JSObject should have fast
// elements.
bool ShouldConvertToFastElements();
// Returns true if the elements of JSObject contains only values that can be
// represented in a FixedDoubleArray and has at least one value that can only
// be represented as a double and not a Smi.
bool ShouldConvertToFastDoubleElements(bool* has_smi_only_elements);
ElementsKind BestFittingFastElementsKind();
// Computes the new capacity when expanding the elements of a JSObject.
static uint32_t NewElementsCapacity(uint32_t old_capacity) {
......@@ -2040,27 +2037,6 @@ class JSObject: public JSReceiver {
static void UpdateAllocationSite(Handle<JSObject> object,
ElementsKind to_kind);
enum SetFastElementsCapacitySmiMode {
kAllowSmiElements,
kForceSmiElements,
kDontAllowSmiElements
};
static Handle<FixedArray> SetFastElementsCapacity(
Handle<JSObject> object, int capacity,
SetFastElementsCapacitySmiMode smi_mode);
// Replace the elements' backing store with fast elements of the given
// capacity. Update the length for JSArrays. Returns the new backing
// store.
static Handle<FixedArray> SetFastElementsCapacityAndLength(
Handle<JSObject> object,
int capacity,
int length,
SetFastElementsCapacitySmiMode smi_mode);
static void SetFastDoubleElementsCapacityAndLength(Handle<JSObject> object,
int capacity, int length);
// Lookup interceptors are used for handling properties controlled by host
// objects.
inline bool HasNamedInterceptor();
......
......@@ -102,6 +102,7 @@ RUNTIME_FUNCTION(Runtime_PushIfAbsent) {
// Strict not needed. Used for cycle detection in Array join implementation.
RETURN_FAILURE_ON_EXCEPTION(
isolate, JSObject::AddDataElement(array, length, element, NONE));
JSObject::ValidateElements(array);
return isolate->heap()->true_value();
}
......
......@@ -576,6 +576,7 @@ RUNTIME_FUNCTION(Runtime_AppendElement) {
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result, JSObject::AddDataElement(array, index, value, NONE));
JSObject::ValidateElements(array);
return *array;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment