Distinguish slow from fast sloppy arguments

BUG=v8:4137
LOG=n

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

Cr-Commit-Position: refs/heads/master@{#29447}
This commit is contained in:
verwaest 2015-07-02 07:38:37 -07:00 committed by Commit bot
parent 3f5d39a1d6
commit c8211b64cd
34 changed files with 513 additions and 496 deletions

View File

@ -6947,7 +6947,7 @@ class Internals {
static const int kJSObjectHeaderSize = 3 * kApiPointerSize;
static const int kFixedArrayHeaderSize = 2 * kApiPointerSize;
static const int kContextHeaderSize = 2 * kApiPointerSize;
static const int kContextEmbedderDataIndex = 80;
static const int kContextEmbedderDataIndex = 81;
static const int kFullStringRepresentationMask = 0x07;
static const int kStringEncodingMask = 0x4;
static const int kExternalTwoByteRepresentationTag = 0x02;

View File

@ -1676,7 +1676,7 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
const int kNormalOffset =
Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX);
const int kAliasedOffset =
Context::SlotOffset(Context::ALIASED_ARGUMENTS_MAP_INDEX);
Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX);
__ ldr(r4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
__ ldr(r4, FieldMemOperand(r4, GlobalObject::kNativeContextOffset));

View File

@ -3225,7 +3225,8 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
case FAST_ELEMENTS:
case FAST_SMI_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}
@ -4322,7 +4323,8 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
case FAST_HOLEY_ELEMENTS:
case FAST_HOLEY_SMI_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}

View File

@ -1880,8 +1880,9 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
__ Ldr(sloppy_args_map,
ContextMemOperand(global_ctx, Context::SLOPPY_ARGUMENTS_MAP_INDEX));
__ Ldr(aliased_args_map,
ContextMemOperand(global_ctx, Context::ALIASED_ARGUMENTS_MAP_INDEX));
__ Ldr(
aliased_args_map,
ContextMemOperand(global_ctx, Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX));
__ Cmp(mapped_params, 0);
__ CmovX(sloppy_args_map, aliased_args_map, ne);

View File

@ -3481,7 +3481,8 @@ void LCodeGen::DoLoadKeyedExternal(LLoadKeyedExternal* instr) {
case FAST_ELEMENTS:
case FAST_SMI_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}
@ -5192,7 +5193,8 @@ void LCodeGen::DoStoreKeyedExternal(LStoreKeyedExternal* instr) {
case FAST_HOLEY_ELEMENTS:
case FAST_HOLEY_SMI_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}

View File

@ -1357,12 +1357,17 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
DCHECK(IsFastObjectElementsKind(map->elements_kind()));
}
{ // --- aliased arguments map
Handle<Map> map =
Map::Copy(isolate->sloppy_arguments_map(), "AliasedArguments");
map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
{ // --- fast and slow aliased arguments map
Handle<Map> map = isolate->sloppy_arguments_map();
map = Map::Copy(map, "FastAliasedArguments");
map->set_elements_kind(FAST_SLOPPY_ARGUMENTS_ELEMENTS);
DCHECK_EQ(2, map->pre_allocated_property_fields());
native_context()->set_aliased_arguments_map(*map);
native_context()->set_fast_aliased_arguments_map(*map);
map = Map::Copy(map, "SlowAliasedArguments");
map->set_elements_kind(SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
DCHECK_EQ(2, map->pre_allocated_property_fields());
native_context()->set_slow_aliased_arguments_map(*map);
}
{ // --- strict mode arguments map
@ -2438,7 +2443,14 @@ bool Genesis::InstallNatives() {
{
AccessorConstantDescriptor d(factory()->iterator_symbol(),
arguments_iterator, attribs);
Handle<Map> map(native_context()->aliased_arguments_map());
Handle<Map> map(native_context()->fast_aliased_arguments_map());
Map::EnsureDescriptorSlack(map, 1);
map->AppendDescriptor(&d);
}
{
AccessorConstantDescriptor d(factory()->iterator_symbol(),
arguments_iterator, attribs);
Handle<Map> map(native_context()->slow_aliased_arguments_map());
Map::EnsureDescriptorSlack(map, 1);
map->AppendDescriptor(&d);
}

View File

@ -2096,9 +2096,11 @@ HValue* CodeStubGraphBuilder<KeyedLoadGenericStub>::BuildCodeStub() {
}
kind_if.Else();
// The SLOPPY_ARGUMENTS_ELEMENTS check generates a "kind_if.Then"
// The SLOW_SLOPPY_ARGUMENTS_ELEMENTS check generates a "kind_if.Then"
STATIC_ASSERT(FAST_SLOPPY_ARGUMENTS_ELEMENTS <
SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
BuildElementsKindLimitCheck(&kind_if, bit_field2,
SLOPPY_ARGUMENTS_ELEMENTS);
SLOW_SLOPPY_ARGUMENTS_ELEMENTS);
// Non-strict elements are not handled.
Add<HDeoptimize>(Deoptimizer::kNonStrictElementsInKeyedLoadGenericStub,
Deoptimizer::EAGER);

View File

@ -810,7 +810,8 @@ void StoreElementStub::Generate(MacroAssembler* masm) {
case DICTIONARY_ELEMENTS:
ElementHandlerCompiler::GenerateStoreSlow(masm);
break;
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}

View File

@ -138,7 +138,8 @@ enum BindingFlags {
V(BOUND_FUNCTION_MAP_INDEX, Map, bound_function_map) \
V(REGEXP_RESULT_MAP_INDEX, Map, regexp_result_map) \
V(SLOPPY_ARGUMENTS_MAP_INDEX, Map, sloppy_arguments_map) \
V(ALIASED_ARGUMENTS_MAP_INDEX, Map, aliased_arguments_map) \
V(FAST_ALIASED_ARGUMENTS_MAP_INDEX, Map, fast_aliased_arguments_map) \
V(SLOW_ALIASED_ARGUMENTS_MAP_INDEX, Map, slow_aliased_arguments_map) \
V(STRICT_ARGUMENTS_MAP_INDEX, Map, strict_arguments_map) \
V(MESSAGE_LISTENERS_INDEX, JSObject, message_listeners) \
V(MAKE_MESSAGE_FUN_INDEX, JSFunction, make_message_fun) \
@ -337,7 +338,8 @@ class Context: public FixedArray {
GLOBAL_PROXY_INDEX = MIN_CONTEXT_SLOTS,
SECURITY_TOKEN_INDEX,
SLOPPY_ARGUMENTS_MAP_INDEX,
ALIASED_ARGUMENTS_MAP_INDEX,
FAST_ALIASED_ARGUMENTS_MAP_INDEX,
SLOW_ALIASED_ARGUMENTS_MAP_INDEX,
STRICT_ARGUMENTS_MAP_INDEX,
REGEXP_RESULT_MAP_INDEX,
SLOPPY_FUNCTION_MAP_INDEX,

View File

@ -44,7 +44,8 @@ int ElementsKindToShiftSize(ElementsKind elements_kind) {
case FAST_HOLEY_SMI_ELEMENTS:
case FAST_HOLEY_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
return kPointerSizeLog2;
}
UNREACHABLE();
@ -134,21 +135,6 @@ ElementsKind GetNextTransitionElementsKind(ElementsKind kind) {
}
ElementsKind GetNextMoreGeneralFastElementsKind(ElementsKind elements_kind,
bool allow_only_packed) {
DCHECK(IsFastElementsKind(elements_kind));
DCHECK(elements_kind != TERMINAL_FAST_ELEMENTS_KIND);
while (true) {
elements_kind = GetNextTransitionElementsKind(elements_kind);
if (!IsFastHoleyElementsKind(elements_kind) || !allow_only_packed) {
return elements_kind;
}
}
UNREACHABLE();
return TERMINAL_FAST_ELEMENTS_KIND;
}
static bool IsTypedArrayElementsKind(ElementsKind elements_kind) {
return IsFixedTypedArrayElementsKind(elements_kind) ||
IsExternalArrayElementsKind(elements_kind);

View File

@ -28,7 +28,10 @@ enum ElementsKind {
// The "slow" kind.
DICTIONARY_ELEMENTS,
SLOPPY_ARGUMENTS_ELEMENTS,
FAST_SLOPPY_ARGUMENTS_ELEMENTS,
SLOW_SLOPPY_ARGUMENTS_ELEMENTS,
// The "fast" kind for external arrays
EXTERNAL_INT8_ELEMENTS,
EXTERNAL_UINT8_ELEMENTS,
@ -88,7 +91,8 @@ inline bool IsDictionaryElementsKind(ElementsKind kind) {
inline bool IsSloppyArgumentsElements(ElementsKind kind) {
return kind == SLOPPY_ARGUMENTS_ELEMENTS;
return kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS ||
kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
}
@ -117,7 +121,8 @@ inline bool IsFastElementsKind(ElementsKind kind) {
inline bool IsTransitionElementsKind(ElementsKind kind) {
return IsFastElementsKind(kind) || IsFixedTypedArrayElementsKind(kind);
return IsFastElementsKind(kind) || IsFixedTypedArrayElementsKind(kind) ||
kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS;
}
@ -239,19 +244,6 @@ inline bool IsTransitionableFastElementsKind(ElementsKind from_kind) {
}
ElementsKind GetNextMoreGeneralFastElementsKind(ElementsKind elements_kind,
bool allow_only_packed);
inline bool CanTransitionToMoreGeneralFastElementsKind(
ElementsKind elements_kind,
bool allow_only_packed) {
return IsFastElementsKind(elements_kind) &&
(elements_kind != TERMINAL_FAST_ELEMENTS_KIND &&
(!allow_only_packed || elements_kind != FAST_ELEMENTS));
}
} } // namespace v8::internal
#endif // V8_ELEMENTS_KIND_H_

View File

@ -47,6 +47,8 @@
// - FixedUint8ClampedElementsAccessor
// - DictionaryElementsAccessor
// - SloppyArgumentsElementsAccessor
// - FastSloppyArgumentsElementsAccessor
// - SlowSloppyArgumentsElementsAccessor
namespace v8 {
@ -61,48 +63,45 @@ static const int kPackedSizeNotKnown = -1;
// fast element handler for smi-only arrays. The implementation is currently
// identical. Note that the order must match that of the ElementsKind enum for
// the |accessor_array[]| below to work.
#define ELEMENTS_LIST(V) \
V(FastPackedSmiElementsAccessor, FAST_SMI_ELEMENTS, FixedArray) \
V(FastHoleySmiElementsAccessor, FAST_HOLEY_SMI_ELEMENTS, \
FixedArray) \
V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \
V(FastHoleyObjectElementsAccessor, FAST_HOLEY_ELEMENTS, FixedArray) \
V(FastPackedDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, \
FixedDoubleArray) \
V(FastHoleyDoubleElementsAccessor, FAST_HOLEY_DOUBLE_ELEMENTS, \
FixedDoubleArray) \
V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, \
SeededNumberDictionary) \
V(SloppyArgumentsElementsAccessor, SLOPPY_ARGUMENTS_ELEMENTS, \
FixedArray) \
V(ExternalInt8ElementsAccessor, EXTERNAL_INT8_ELEMENTS, \
ExternalInt8Array) \
V(ExternalUint8ElementsAccessor, \
EXTERNAL_UINT8_ELEMENTS, ExternalUint8Array) \
V(ExternalInt16ElementsAccessor, EXTERNAL_INT16_ELEMENTS, \
ExternalInt16Array) \
V(ExternalUint16ElementsAccessor, \
EXTERNAL_UINT16_ELEMENTS, ExternalUint16Array) \
V(ExternalInt32ElementsAccessor, EXTERNAL_INT32_ELEMENTS, \
ExternalInt32Array) \
V(ExternalUint32ElementsAccessor, \
EXTERNAL_UINT32_ELEMENTS, ExternalUint32Array) \
V(ExternalFloat32ElementsAccessor, \
EXTERNAL_FLOAT32_ELEMENTS, ExternalFloat32Array) \
V(ExternalFloat64ElementsAccessor, \
EXTERNAL_FLOAT64_ELEMENTS, ExternalFloat64Array) \
V(ExternalUint8ClampedElementsAccessor, \
EXTERNAL_UINT8_CLAMPED_ELEMENTS, \
ExternalUint8ClampedArray) \
V(FixedUint8ElementsAccessor, UINT8_ELEMENTS, FixedUint8Array) \
V(FixedInt8ElementsAccessor, INT8_ELEMENTS, FixedInt8Array) \
V(FixedUint16ElementsAccessor, UINT16_ELEMENTS, FixedUint16Array) \
V(FixedInt16ElementsAccessor, INT16_ELEMENTS, FixedInt16Array) \
V(FixedUint32ElementsAccessor, UINT32_ELEMENTS, FixedUint32Array) \
V(FixedInt32ElementsAccessor, INT32_ELEMENTS, FixedInt32Array) \
V(FixedFloat32ElementsAccessor, FLOAT32_ELEMENTS, FixedFloat32Array) \
V(FixedFloat64ElementsAccessor, FLOAT64_ELEMENTS, FixedFloat64Array) \
V(FixedUint8ClampedElementsAccessor, UINT8_CLAMPED_ELEMENTS, \
#define ELEMENTS_LIST(V) \
V(FastPackedSmiElementsAccessor, FAST_SMI_ELEMENTS, FixedArray) \
V(FastHoleySmiElementsAccessor, FAST_HOLEY_SMI_ELEMENTS, FixedArray) \
V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \
V(FastHoleyObjectElementsAccessor, FAST_HOLEY_ELEMENTS, FixedArray) \
V(FastPackedDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, FixedDoubleArray) \
V(FastHoleyDoubleElementsAccessor, FAST_HOLEY_DOUBLE_ELEMENTS, \
FixedDoubleArray) \
V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, SeededNumberDictionary) \
V(FastSloppyArgumentsElementsAccessor, FAST_SLOPPY_ARGUMENTS_ELEMENTS, \
FixedArray) \
V(SlowSloppyArgumentsElementsAccessor, SLOW_SLOPPY_ARGUMENTS_ELEMENTS, \
FixedArray) \
V(ExternalInt8ElementsAccessor, EXTERNAL_INT8_ELEMENTS, ExternalInt8Array) \
V(ExternalUint8ElementsAccessor, EXTERNAL_UINT8_ELEMENTS, \
ExternalUint8Array) \
V(ExternalInt16ElementsAccessor, EXTERNAL_INT16_ELEMENTS, \
ExternalInt16Array) \
V(ExternalUint16ElementsAccessor, EXTERNAL_UINT16_ELEMENTS, \
ExternalUint16Array) \
V(ExternalInt32ElementsAccessor, EXTERNAL_INT32_ELEMENTS, \
ExternalInt32Array) \
V(ExternalUint32ElementsAccessor, EXTERNAL_UINT32_ELEMENTS, \
ExternalUint32Array) \
V(ExternalFloat32ElementsAccessor, EXTERNAL_FLOAT32_ELEMENTS, \
ExternalFloat32Array) \
V(ExternalFloat64ElementsAccessor, EXTERNAL_FLOAT64_ELEMENTS, \
ExternalFloat64Array) \
V(ExternalUint8ClampedElementsAccessor, EXTERNAL_UINT8_CLAMPED_ELEMENTS, \
ExternalUint8ClampedArray) \
V(FixedUint8ElementsAccessor, UINT8_ELEMENTS, FixedUint8Array) \
V(FixedInt8ElementsAccessor, INT8_ELEMENTS, FixedInt8Array) \
V(FixedUint16ElementsAccessor, UINT16_ELEMENTS, FixedUint16Array) \
V(FixedInt16ElementsAccessor, INT16_ELEMENTS, FixedInt16Array) \
V(FixedUint32ElementsAccessor, UINT32_ELEMENTS, FixedUint32Array) \
V(FixedInt32ElementsAccessor, INT32_ELEMENTS, FixedInt32Array) \
V(FixedFloat32ElementsAccessor, FLOAT32_ELEMENTS, FixedFloat32Array) \
V(FixedFloat64ElementsAccessor, FLOAT64_ELEMENTS, FixedFloat64Array) \
V(FixedUint8ClampedElementsAccessor, UINT8_CLAMPED_ELEMENTS, \
FixedUint8ClampedArray)
@ -550,6 +549,9 @@ template <typename ElementsAccessorSubclass,
typename ElementsTraitsParam>
class ElementsAccessorBase : public ElementsAccessor {
protected:
template <typename SloppyArgumentsElementsAccessorSubclass,
typename ArgumentsAccessor, typename KindTraits>
friend class SloppyArgumentsElementsAccessor;
explicit ElementsAccessorBase(const char* name)
: ElementsAccessor(name) { }
@ -922,6 +924,12 @@ class ElementsAccessorBase : public ElementsAccessor {
};
class FastSloppyArgumentsElementsAccessor;
class FastHoleyObjectElementsAccessor;
template <typename SloppyArgumentsElementsAccessorSubclass,
typename ArgumentsAccessor, typename KindTraits>
class SloppyArgumentsElementsAccessor;
// Super class for all fast element arrays.
template<typename FastElementsAccessorSubclass,
typename KindTraits>
@ -934,7 +942,9 @@ class FastElementsAccessor
protected:
friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
friend class SloppyArgumentsElementsAccessor;
friend class SloppyArgumentsElementsAccessor<
FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
typedef typename KindTraits::BackingStore BackingStore;
@ -1066,33 +1076,6 @@ class FastElementsAccessor
};
static inline ElementsKind ElementsKindForArray(FixedArrayBase* array) {
switch (array->map()->instance_type()) {
case FIXED_ARRAY_TYPE:
if (array->IsDictionary()) {
return DICTIONARY_ELEMENTS;
} else {
return FAST_HOLEY_ELEMENTS;
}
case FIXED_DOUBLE_ARRAY_TYPE:
return FAST_HOLEY_DOUBLE_ELEMENTS;
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case EXTERNAL_##TYPE##_ARRAY_TYPE: \
return EXTERNAL_##TYPE##_ELEMENTS; \
case FIXED_##TYPE##_ARRAY_TYPE: \
return TYPE##_ELEMENTS;
TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
default:
UNREACHABLE();
}
return FAST_HOLEY_ELEMENTS;
}
template<typename FastElementsAccessorSubclass,
typename KindTraits>
class FastSmiOrObjectElementsAccessor
@ -1132,17 +1115,9 @@ class FastSmiOrObjectElementsAccessor
CopyDictionaryToObjectElements(from, from_start, to, to_kind, to_start,
copy_size);
break;
case SLOPPY_ARGUMENTS_ELEMENTS: {
// TODO(verwaest): This is a temporary hack to support extending
// SLOPPY_ARGUMENTS_ELEMENTS in GrowCapacityAndConvert.
// This case should be UNREACHABLE().
FixedArray* parameter_map = FixedArray::cast(from);
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
ElementsKind from_kind = ElementsKindForArray(arguments);
CopyElementsImpl(arguments, from_start, to, from_kind,
to_start, packed_size, copy_size);
break;
}
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case EXTERNAL_##TYPE##_ELEMENTS: \
case TYPE##_ELEMENTS: \
@ -1237,7 +1212,8 @@ class FastDoubleElementsAccessor
CopyDictionaryToDoubleElements(from, from_start, to, to_start,
copy_size);
break;
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
@ -1355,6 +1331,8 @@ TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR)
#undef FIXED_ELEMENTS_ACCESSOR
class SlowSloppyArgumentsElementsAccessor;
class DictionaryElementsAccessor
: public ElementsAccessorBase<DictionaryElementsAccessor,
@ -1417,13 +1395,28 @@ class DictionaryElementsAccessor
array->set_length(*length_obj);
}
static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
FixedArrayBase* to, ElementsKind from_kind,
uint32_t to_start, int packed_size,
int copy_size) {
UNREACHABLE();
}
protected:
friend class ElementsAccessorBase<DictionaryElementsAccessor,
ElementsKindTraits<DICTIONARY_ELEMENTS> >;
friend class SlowSloppyArgumentsElementsAccessor;
friend class SloppyArgumentsElementsAccessor<
SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >;
static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
LanguageMode language_mode) {
Isolate* isolate = obj->GetIsolate();
Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()),
isolate);
bool is_arguments =
(obj->GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS);
bool is_arguments = obj->HasSloppyArgumentsElements();
if (is_arguments) {
backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate);
}
@ -1446,18 +1439,6 @@ class DictionaryElementsAccessor
}
}
static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
FixedArrayBase* to, ElementsKind from_kind,
uint32_t to_start, int packed_size,
int copy_size) {
UNREACHABLE();
}
protected:
friend class ElementsAccessorBase<DictionaryElementsAccessor,
ElementsKindTraits<DICTIONARY_ELEMENTS> >;
virtual void Delete(Handle<JSObject> obj, uint32_t key,
LanguageMode language_mode) final {
DeleteCommon(obj, key, language_mode);
@ -1556,18 +1537,19 @@ class DictionaryElementsAccessor
};
class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
SloppyArgumentsElementsAccessor,
ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> > {
template <typename SloppyArgumentsElementsAccessorSubclass,
typename ArgumentsAccessor, typename KindTraits>
class SloppyArgumentsElementsAccessor
: public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
KindTraits> {
public:
explicit SloppyArgumentsElementsAccessor(const char* name)
: ElementsAccessorBase<
SloppyArgumentsElementsAccessor,
ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
: ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
KindTraits>(name) {}
protected:
friend class ElementsAccessorBase<
SloppyArgumentsElementsAccessor,
ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >;
friend class ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
KindTraits>;
static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
Handle<FixedArrayBase> parameters) {
@ -1584,8 +1566,7 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
// Object is not mapped, defer to the arguments.
Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)),
isolate);
Handle<Object> result =
ElementsAccessor::ForArray(arguments)->Get(obj, key, arguments);
Handle<Object> result = ArgumentsAccessor::GetImpl(obj, key, arguments);
// Elements of the arguments object in slow mode might be slow aliases.
if (result->IsAliasedArgumentsEntry()) {
DisallowHeapAllocation no_gc;
@ -1600,20 +1581,22 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
}
}
virtual void Delete(Handle<JSObject> obj, uint32_t key,
LanguageMode language_mode) final {
FixedArray* parameter_map = FixedArray::cast(obj->elements());
if (!GetParameterMapArg(parameter_map, key)->IsTheHole()) {
// TODO(kmillikin): We could check if this was the last aliased
// parameter, and revert to normal elements in that case. That
// would enable GC of the context.
parameter_map->set_the_hole(key + 2);
} else {
ArgumentsAccessor::DeleteCommon(obj, key, language_mode);
}
}
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);
UNREACHABLE();
}
static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) {
@ -1626,7 +1609,208 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
context->set(context_index, value);
} else {
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
ElementsAccessor::ForArray(arguments)->Set(arguments, key, value);
ArgumentsAccessor::SetImpl(arguments, key, value);
}
}
static MaybeHandle<AccessorPair> GetAccessorPairImpl(
Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> parameters) {
Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
Handle<Object> probe(GetParameterMapArg(*parameter_map, key),
obj->GetIsolate());
if (!probe->IsTheHole()) {
return MaybeHandle<AccessorPair>();
} else {
// If not aliased, check the arguments.
Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
return ArgumentsAccessor::GetAccessorPairImpl(obj, key, arguments);
}
}
static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
Handle<FixedArrayBase> parameter_map) {
// Sloppy arguments objects are not arrays.
UNREACHABLE();
}
static uint32_t GetCapacityImpl(JSObject* holder,
FixedArrayBase* backing_store) {
FixedArray* parameter_map = FixedArray::cast(backing_store);
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
return parameter_map->length() - 2 +
ArgumentsAccessor::GetCapacityImpl(holder, arguments);
}
static bool HasIndexImpl(FixedArrayBase* parameters, uint32_t index) {
FixedArray* parameter_map = FixedArray::cast(parameters);
uint32_t length = parameter_map->length() - 2;
if (index < length) {
return !GetParameterMapArg(parameter_map, index)->IsTheHole();
}
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
return ArgumentsAccessor::HasIndexImpl(arguments, index - length);
}
static uint32_t GetKeyForIndexImpl(FixedArrayBase* parameters,
uint32_t index) {
FixedArray* parameter_map = FixedArray::cast(parameters);
uint32_t length = parameter_map->length() - 2;
if (index < length) return index;
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
return ArgumentsAccessor::GetKeyForIndexImpl(arguments, index - length);
}
static uint32_t GetIndexForKeyImpl(JSObject* holder,
FixedArrayBase* parameters, uint32_t key) {
FixedArray* parameter_map = FixedArray::cast(parameters);
Object* probe = GetParameterMapArg(parameter_map, key);
if (!probe->IsTheHole()) return key;
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
uint32_t index =
ArgumentsAccessor::GetIndexForKeyImpl(holder, arguments, key);
if (index == kMaxUInt32) return index;
return (parameter_map->length() - 2) + index;
}
static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters,
uint32_t index) {
FixedArray* parameter_map = FixedArray::cast(parameters);
uint32_t length = parameter_map->length() - 2;
if (index < length) {
return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
}
index -= length;
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
return ArgumentsAccessor::GetDetailsImpl(arguments, index);
}
static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) {
uint32_t length = parameter_map->length() - 2;
return key < length
? parameter_map->get(key + 2)
: Object::cast(parameter_map->GetHeap()->the_hole_value());
}
};
class FastSloppyArgumentsElementsAccessor
: public SloppyArgumentsElementsAccessor<
FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> > {
public:
friend class SloppyArgumentsElementsAccessor<
FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
friend class ElementsAccessorBase<
FastSloppyArgumentsElementsAccessor,
ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
explicit FastSloppyArgumentsElementsAccessor(const char* name)
: SloppyArgumentsElementsAccessor<
FastSloppyArgumentsElementsAccessor,
FastHoleyObjectElementsAccessor,
ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
protected:
static void AddImpl(Handle<JSObject> object, uint32_t key,
Handle<Object> value, PropertyAttributes attributes,
uint32_t new_capacity) {
DCHECK_EQ(NONE, attributes);
Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
Handle<FixedArrayBase> old_elements(
FixedArrayBase::cast(parameter_map->get(1)));
if (old_elements->IsSeededNumberDictionary() ||
static_cast<uint32_t>(old_elements->length()) < new_capacity) {
GrowCapacityAndConvertImpl(object, new_capacity);
}
SetImpl(object->elements(), key, *value);
}
static void ReconfigureImpl(Handle<JSObject> object,
Handle<FixedArrayBase> store, uint32_t index,
Handle<Object> value,
PropertyAttributes attributes) {
Handle<SeededNumberDictionary> dictionary =
JSObject::NormalizeElements(object);
FixedArray::cast(*store)->set(1, *dictionary);
uint32_t length = static_cast<uint32_t>(store->length()) - 2;
if (index >= length) {
index = dictionary->FindEntry(index - length) + length;
}
object->GetElementsAccessor()->Reconfigure(object, store, index, value,
attributes);
}
static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
FixedArrayBase* to, ElementsKind from_kind,
uint32_t to_start, int packed_size,
int copy_size) {
DCHECK(!to->IsDictionary());
if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) {
CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS,
to_start, copy_size);
} else {
DCHECK_EQ(FAST_SLOPPY_ARGUMENTS_ELEMENTS, from_kind);
CopyObjectToObjectElements(from, FAST_HOLEY_ELEMENTS, from_start, to,
FAST_HOLEY_ELEMENTS, to_start, copy_size);
}
}
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 = object->GetElementsKind();
// This method should only be called if there's a reason to update the
// elements.
DCHECK(from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS ||
static_cast<uint32_t>(old_elements->length()) < capacity);
Handle<FixedArrayBase> elements =
ConvertElementsWithCapacity(object, old_elements, from_kind, capacity);
Handle<Map> new_map = JSObject::GetElementsTransitionMap(
object, FAST_SLOPPY_ARGUMENTS_ELEMENTS);
JSObject::MigrateToMap(object, new_map);
parameter_map->set(1, *elements);
JSObject::ValidateElements(object);
}
};
class SlowSloppyArgumentsElementsAccessor
: public SloppyArgumentsElementsAccessor<
SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > {
public:
friend class ElementsAccessorBase<
SlowSloppyArgumentsElementsAccessor,
ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >;
friend class SloppyArgumentsElementsAccessor<
SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >;
explicit SlowSloppyArgumentsElementsAccessor(const char* name)
: SloppyArgumentsElementsAccessor<
SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
protected:
static void AddImpl(Handle<JSObject> object, uint32_t key,
Handle<Object> value, PropertyAttributes attributes,
uint32_t new_capacity) {
Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
Handle<FixedArrayBase> old_elements(
FixedArrayBase::cast(parameter_map->get(1)));
Handle<SeededNumberDictionary> dictionary =
old_elements->IsSeededNumberDictionary()
? Handle<SeededNumberDictionary>::cast(old_elements)
: JSObject::NormalizeElements(object);
PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
Handle<SeededNumberDictionary> new_dictionary =
SeededNumberDictionary::AddNumberEntry(dictionary, key, value, details);
if (attributes != NONE) new_dictionary->set_requires_slow_elements();
if (*dictionary != *new_dictionary) {
FixedArray::cast(object->elements())->set(1, *new_dictionary);
}
}
@ -1653,168 +1837,21 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
}
PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
Handle<SeededNumberDictionary> arguments =
parameter_map->get(1)->IsSeededNumberDictionary()
? handle(SeededNumberDictionary::cast(parameter_map->get(1)))
: JSObject::NormalizeElements(object);
Handle<SeededNumberDictionary> arguments(
SeededNumberDictionary::cast(parameter_map->get(1)));
arguments = SeededNumberDictionary::AddNumberEntry(arguments, index,
value, details);
parameter_map->set(1, *arguments);
} else {
Handle<FixedArrayBase> arguments(
FixedArrayBase::cast(parameter_map->get(1)));
ElementsAccessor::ForArray(arguments)
->Reconfigure(object, arguments, index - length, value, attributes);
DictionaryElementsAccessor::ReconfigureImpl(
object, arguments, index - length, value, attributes);
}
}
static void AddImpl(Handle<JSObject> object, uint32_t key,
Handle<Object> value, PropertyAttributes attributes,
uint32_t new_capacity) {
DCHECK_EQ(NONE, attributes);
Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
Handle<FixedArrayBase> old_elements(
FixedArrayBase::cast(parameter_map->get(1)));
if (old_elements->IsSeededNumberDictionary() ||
static_cast<uint32_t>(old_elements->length()) < new_capacity) {
GrowCapacityAndConvertImpl(object, new_capacity);
}
SetImpl(object->elements(), key, *value);
}
static MaybeHandle<AccessorPair> GetAccessorPairImpl(
Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> parameters) {
Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
Handle<Object> probe(GetParameterMapArg(*parameter_map, key),
obj->GetIsolate());
if (!probe->IsTheHole()) {
return MaybeHandle<AccessorPair>();
} else {
// If not aliased, check the arguments.
Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
return ElementsAccessor::ForArray(arguments)
->GetAccessorPair(obj, key, arguments);
}
}
static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
Handle<FixedArrayBase> parameter_map) {
// Sloppy arguments objects are not arrays.
UNREACHABLE();
}
virtual void Delete(Handle<JSObject> obj, uint32_t key,
LanguageMode language_mode) final {
Isolate* isolate = obj->GetIsolate();
Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements()));
Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
if (!probe->IsTheHole()) {
// TODO(kmillikin): We could check if this was the last aliased
// parameter, and revert to normal elements in that case. That
// would enable GC of the context.
parameter_map->set_the_hole(key + 2);
} else {
Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
if (arguments->IsDictionary()) {
DictionaryElementsAccessor::DeleteCommon(obj, key, language_mode);
} else {
// It's difficult to access the version of DeleteCommon that is declared
// in the templatized super class, call the concrete implementation in
// the class for the most generalized ElementsKind subclass.
FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, language_mode);
}
}
}
static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
FixedArrayBase* to, ElementsKind from_kind,
uint32_t to_start, int packed_size,
int copy_size) {
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,
FixedArrayBase* backing_store) {
FixedArray* parameter_map = FixedArray::cast(backing_store);
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
return parameter_map->length() - 2 +
ForArray(arguments)->GetCapacity(holder, arguments);
}
static bool HasIndexImpl(FixedArrayBase* parameters, uint32_t index) {
FixedArray* parameter_map = FixedArray::cast(parameters);
uint32_t length = parameter_map->length() - 2;
if (index < length) {
return !GetParameterMapArg(parameter_map, index)->IsTheHole();
}
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
return ForArray(arguments)->HasIndex(arguments, index - length);
}
static uint32_t GetKeyForIndexImpl(FixedArrayBase* parameters,
uint32_t index) {
FixedArray* parameter_map = FixedArray::cast(parameters);
uint32_t length = parameter_map->length() - 2;
if (index < length) return index;
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
return ForArray(arguments)->GetKeyForIndex(arguments, index - length);
}
static uint32_t GetIndexForKeyImpl(JSObject* holder,
FixedArrayBase* parameters, uint32_t key) {
FixedArray* parameter_map = FixedArray::cast(parameters);
Object* probe = GetParameterMapArg(parameter_map, key);
if (!probe->IsTheHole()) return key;
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
uint32_t index = ElementsAccessor::ForArray(arguments)
->GetIndexForKey(holder, arguments, key);
if (index == kMaxUInt32) return index;
return (parameter_map->length() - 2) + index;
}
static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters,
uint32_t index) {
FixedArray* parameter_map = FixedArray::cast(parameters);
uint32_t length = parameter_map->length() - 2;
if (index < length) {
return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
}
index -= length;
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
return ElementsAccessor::ForArray(arguments)->GetDetails(arguments, index);
}
private:
static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) {
uint32_t length = parameter_map->length() - 2;
return key < length
? parameter_map->get(key + 2)
: Object::cast(parameter_map->GetHeap()->the_hole_value());
}
};
ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) {
return elements_accessors_[ElementsKindForArray(array)];
}
ElementsAccessor* ElementsAccessor::ForArray(Handle<FixedArrayBase> array) {
return ForArray(*array);
}
void ElementsAccessor::InitializeOncePerProcess() {
static ElementsAccessor* accessor_array[] = {
#define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind),

View File

@ -149,7 +149,6 @@ class ElementsAccessor {
uint32_t new_capacity) = 0;
protected:
friend class SloppyArgumentsElementsAccessor;
friend class LookupIterator;
static ElementsAccessor* ForArray(FixedArrayBase* array);

View File

@ -7157,7 +7157,8 @@ HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess(
static bool CanInlineElementAccess(Handle<Map> map) {
return map->IsJSObjectMap() && !map->has_slow_elements_kind() &&
return map->IsJSObjectMap() && !map->has_dictionary_elements() &&
!map->has_sloppy_arguments_elements() &&
!map->has_indexed_interceptor() && !map->is_access_check_needed();
}
@ -7263,7 +7264,7 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
elements_kind != GetInitialFastElementsKind()) {
possible_transitioned_maps.Add(map);
}
if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) {
if (IsSloppyArgumentsElements(elements_kind)) {
HInstruction* result = BuildKeyedGeneric(access_type, expr, object, key,
val);
*has_side_effects = result->HasObservableSideEffects();
@ -7274,7 +7275,7 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
for (int i = 0; i < maps->length(); ++i) {
Handle<Map> map = maps->at(i);
Handle<Map> transitioned_map =
map->FindTransitionedMap(&possible_transitioned_maps);
Map::FindTransitionedMap(map, &possible_transitioned_maps);
transition_target.Add(transitioned_map);
}

View File

@ -899,9 +899,8 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
__ jmp(&instantiate, Label::kNear);
__ bind(&has_mapped_parameters);
__ mov(
edi,
Operand(edi, Context::SlotOffset(Context::ALIASED_ARGUMENTS_MAP_INDEX)));
__ mov(edi, Operand(edi, Context::SlotOffset(
Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)));
__ bind(&instantiate);
// eax = address of new object (tagged)

View File

@ -3092,7 +3092,8 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
case FAST_HOLEY_ELEMENTS:
case FAST_HOLEY_DOUBLE_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}
@ -4192,7 +4193,8 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
case FAST_HOLEY_ELEMENTS:
case FAST_HOLEY_DOUBLE_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}

View File

@ -349,7 +349,7 @@ Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
Handle<Map> receiver_map(receiver_maps->at(i));
Handle<Code> cached_stub;
Handle<Map> transitioned_map =
receiver_map->FindTransitionedMap(receiver_maps);
Map::FindTransitionedMap(receiver_map, receiver_maps);
// TODO(mvstanton): The code below is doing pessimistic elements
// transitions. I would like to stop doing that and rely on Allocation Site

View File

@ -1779,7 +1779,7 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
const int kNormalOffset =
Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX);
const int kAliasedOffset =
Context::SlotOffset(Context::ALIASED_ARGUMENTS_MAP_INDEX);
Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX);
__ lw(t0, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
__ lw(t0, FieldMemOperand(t0, GlobalObject::kNativeContextOffset));

View File

@ -3149,7 +3149,8 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
case FAST_HOLEY_ELEMENTS:
case FAST_HOLEY_SMI_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}
@ -4283,7 +4284,8 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
case FAST_HOLEY_ELEMENTS:
case FAST_HOLEY_SMI_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}

View File

@ -1778,7 +1778,7 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
const int kNormalOffset =
Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX);
const int kAliasedOffset =
Context::SlotOffset(Context::ALIASED_ARGUMENTS_MAP_INDEX);
Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX);
__ ld(a4, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
__ ld(a4, FieldMemOperand(a4, GlobalObject::kNativeContextOffset));

View File

@ -3278,7 +3278,8 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
case FAST_HOLEY_ELEMENTS:
case FAST_HOLEY_SMI_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}
@ -4485,7 +4486,8 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
case FAST_HOLEY_ELEMENTS:
case FAST_HOLEY_SMI_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}

View File

@ -257,7 +257,7 @@ void JSObject::JSObjectVerify() {
VerifyHeapPointer(properties());
VerifyHeapPointer(elements());
if (GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS) {
if (HasSloppyArgumentsElements()) {
CHECK(this->elements()->IsFixedArray());
CHECK_GE(this->elements()->length(), 2);
}
@ -1104,7 +1104,8 @@ void JSObject::IncrementSpillStatistics(SpillInformation* info) {
dict->Capacity() - dict->NumberOfElements();
break;
}
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
break;
}
}

View File

@ -6223,7 +6223,7 @@ ElementsKind JSObject::GetElementsKind() {
fixed_array->IsFixedArray() &&
fixed_array->IsDictionary()) ||
(kind > DICTIONARY_ELEMENTS));
DCHECK((kind != SLOPPY_ARGUMENTS_ELEMENTS) ||
DCHECK(!IsSloppyArgumentsElements(kind) ||
(elements()->IsFixedArray() && elements()->length() >= 2));
}
#endif
@ -6266,8 +6266,18 @@ bool JSObject::HasDictionaryElements() {
}
bool JSObject::HasFastArgumentsElements() {
return GetElementsKind() == FAST_SLOPPY_ARGUMENTS_ELEMENTS;
}
bool JSObject::HasSlowArgumentsElements() {
return GetElementsKind() == SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
}
bool JSObject::HasSloppyArgumentsElements() {
return GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS;
return IsSloppyArgumentsElements(GetElementsKind());
}

View File

@ -340,7 +340,8 @@ void JSObject::PrintElements(std::ostream& os) { // NOLINT
case DICTIONARY_ELEMENTS:
elements()->Print(os);
break;
case SLOPPY_ARGUMENTS_ELEMENTS: {
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
FixedArray* p = FixedArray::cast(elements());
os << " parameter map:";
for (int i = 2; i < p->length(); i++) {

View File

@ -2425,7 +2425,9 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map> old_map, int modify_index,
ElementsKind from_kind = root_map->elements_kind();
ElementsKind to_kind = old_map->elements_kind();
// TODO(ishell): Add a test for SLOW_SLOPPY_ARGUMENTS_ELEMENTS.
if (from_kind != to_kind && to_kind != DICTIONARY_ELEMENTS &&
to_kind != SLOW_SLOPPY_ARGUMENTS_ELEMENTS &&
!(IsTransitionableFastElementsKind(from_kind) &&
IsMoreGeneralElementsKindTransition(from_kind, to_kind))) {
return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
@ -3586,51 +3588,38 @@ int AccessorInfo::AppendUnique(Handle<Object> descriptors,
}
static bool ContainsMap(MapHandleList* maps, Handle<Map> map) {
DCHECK(!map.is_null());
static bool ContainsMap(MapHandleList* maps, Map* map) {
DCHECK_NOT_NULL(map);
for (int i = 0; i < maps->length(); ++i) {
if (!maps->at(i).is_null() && maps->at(i).is_identical_to(map)) return true;
if (!maps->at(i).is_null() && *maps->at(i) == map) return true;
}
return false;
}
template <class T>
static Handle<T> MaybeNull(T* p) {
if (p == NULL) return Handle<T>::null();
return Handle<T>(p);
}
Handle<Map> Map::FindTransitionedMap(MapHandleList* candidates) {
ElementsKind kind = elements_kind();
Handle<Map> transitioned_map = Handle<Map>::null();
Handle<Map> current_map(this);
Handle<Map> Map::FindTransitionedMap(Handle<Map> map,
MapHandleList* candidates) {
ElementsKind kind = map->elements_kind();
bool packed = IsFastPackedElementsKind(kind);
Map* transition = nullptr;
if (IsTransitionableFastElementsKind(kind)) {
while (CanTransitionToMoreGeneralFastElementsKind(kind, false)) {
kind = GetNextMoreGeneralFastElementsKind(kind, false);
Handle<Map> maybe_transitioned_map =
MaybeNull(current_map->LookupElementsTransitionMap(kind));
if (maybe_transitioned_map.is_null()) break;
if (ContainsMap(candidates, maybe_transitioned_map) &&
(packed || !IsFastPackedElementsKind(kind))) {
transitioned_map = maybe_transitioned_map;
if (!IsFastPackedElementsKind(kind)) packed = false;
for (Map* current = map->ElementsTransitionMap();
current != nullptr && current->has_fast_elements();
current = current->ElementsTransitionMap()) {
if (ContainsMap(candidates, current) &&
(packed || !IsFastPackedElementsKind(current->elements_kind()))) {
transition = current;
packed = packed && IsFastPackedElementsKind(current->elements_kind());
}
current_map = maybe_transitioned_map;
}
}
return transitioned_map;
return transition == nullptr ? Handle<Map>() : handle(transition);
}
static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) {
Map* current_map = map;
int target_kind =
IsFastElementsKind(to_kind) || IsExternalArrayElementsKind(to_kind)
? to_kind
: TERMINAL_FAST_ELEMENTS_KIND;
// Support for legacy API: SetIndexedPropertiesTo{External,Pixel}Data
// allows to change elements from arbitrary kind to any ExternalArray
@ -3646,20 +3635,14 @@ static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) {
}
ElementsKind kind = map->elements_kind();
while (kind != target_kind) {
kind = GetNextTransitionElementsKind(kind);
while (kind != to_kind) {
Map* next_map = current_map->ElementsTransitionMap();
if (next_map == NULL) return current_map;
if (next_map == nullptr) return current_map;
kind = next_map->elements_kind();
current_map = next_map;
}
Map* next_map = current_map->ElementsTransitionMap();
if (to_kind != kind && next_map != NULL) {
DCHECK(to_kind == DICTIONARY_ELEMENTS);
if (next_map->elements_kind() == to_kind) return next_map;
}
DCHECK(current_map->elements_kind() == target_kind);
DCHECK_EQ(to_kind, current_map->elements_kind());
return current_map;
}
@ -3667,7 +3650,7 @@ static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) {
Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) {
Map* to_map = FindClosestElementsTransition(this, to_kind);
if (to_map->elements_kind() == to_kind) return to_map;
return NULL;
return nullptr;
}
@ -3708,9 +3691,11 @@ static Handle<Map> AddMissingElementsTransitions(Handle<Map> map,
flag = OMIT_TRANSITION;
} else {
flag = INSERT_TRANSITION;
while (kind != to_kind && !IsTerminalElementsKind(kind)) {
kind = GetNextTransitionElementsKind(kind);
current_map = Map::CopyAsElementsKind(current_map, kind, flag);
if (IsFastElementsKind(kind)) {
while (kind != to_kind && !IsTerminalElementsKind(kind)) {
kind = GetNextTransitionElementsKind(kind);
current_map = Map::CopyAsElementsKind(current_map, kind, flag);
}
}
}
@ -3732,16 +3717,28 @@ Handle<Map> Map::TransitionElementsTo(Handle<Map> map,
Isolate* isolate = map->GetIsolate();
Context* native_context = isolate->context()->native_context();
Object* maybe_array_maps = map->is_strong()
? native_context->js_array_strong_maps()
: native_context->js_array_maps();
if (maybe_array_maps->IsFixedArray()) {
DisallowHeapAllocation no_gc;
FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
if (array_maps->get(from_kind) == *map) {
Object* maybe_transitioned_map = array_maps->get(to_kind);
if (maybe_transitioned_map->IsMap()) {
return handle(Map::cast(maybe_transitioned_map));
if (from_kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS) {
if (*map == native_context->fast_aliased_arguments_map()) {
DCHECK_EQ(SLOW_SLOPPY_ARGUMENTS_ELEMENTS, to_kind);
return handle(native_context->slow_aliased_arguments_map());
}
} else if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) {
if (*map == native_context->slow_aliased_arguments_map()) {
DCHECK_EQ(FAST_SLOPPY_ARGUMENTS_ELEMENTS, to_kind);
return handle(native_context->fast_aliased_arguments_map());
}
} else {
Object* maybe_array_maps = map->is_strong()
? native_context->js_array_strong_maps()
: native_context->js_array_maps();
if (maybe_array_maps->IsFixedArray()) {
DisallowHeapAllocation no_gc;
FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
if (array_maps->get(from_kind) == *map) {
Object* maybe_transitioned_map = array_maps->get(to_kind);
if (maybe_transitioned_map->IsMap()) {
return handle(Map::cast(maybe_transitioned_map));
}
}
}
}
@ -3750,8 +3747,8 @@ Handle<Map> Map::TransitionElementsTo(Handle<Map> map,
bool allow_store_transition = IsTransitionElementsKind(from_kind);
// Only store fast element maps in ascending generality.
if (IsFastElementsKind(to_kind)) {
allow_store_transition &=
IsTransitionableFastElementsKind(from_kind) &&
allow_store_transition =
allow_store_transition && IsTransitionableFastElementsKind(from_kind) &&
IsMoreGeneralElementsKindTransition(from_kind, to_kind);
}
@ -4844,15 +4841,15 @@ Handle<SeededNumberDictionary> JSObject::NormalizeElements(
dictionary = CopyFastElementsToDictionary(array, length, dictionary);
// Switch to using the dictionary as the backing storage for elements.
ElementsKind target_kind =
is_arguments ? SLOW_SLOPPY_ARGUMENTS_ELEMENTS : DICTIONARY_ELEMENTS;
Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind);
// Set the new map first to satify the elements type assert in set_elements().
JSObject::MigrateToMap(object, new_map);
if (is_arguments) {
FixedArray::cast(object->elements())->set(1, *dictionary);
} else {
// Set the new map first to satify the elements type assert in
// set_elements().
Handle<Map> new_map =
JSObject::GetElementsTransitionMap(object, DICTIONARY_ELEMENTS);
JSObject::MigrateToMap(object, new_map);
object->set_elements(*dictionary);
}
@ -4866,8 +4863,7 @@ Handle<SeededNumberDictionary> JSObject::NormalizeElements(
}
#endif
DCHECK(object->HasDictionaryElements() ||
object->HasDictionaryArgumentsElements());
DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements());
return dictionary;
}
@ -5371,7 +5367,8 @@ bool JSObject::ReferencesObject(Object* obj) {
if (ReferencesObjectFromElements(elements, kind, obj)) return true;
break;
}
case SLOPPY_ARGUMENTS_ELEMENTS: {
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
FixedArray* parameter_map = FixedArray::cast(elements());
// Check the mapped parameters.
int length = parameter_map->length();
@ -5469,8 +5466,7 @@ MaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
// If there are fast elements we normalize.
Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
DCHECK(object->HasDictionaryElements() ||
object->HasDictionaryArgumentsElements());
DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements());
// Make sure that we never go back to fast case.
dictionary->set_requires_slow_elements();
@ -5898,7 +5894,8 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
}
break;
}
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNIMPLEMENTED();
break;
@ -6315,7 +6312,8 @@ void JSObject::DefineElementAccessor(Handle<JSObject> object,
return;
}
break;
case SLOPPY_ARGUMENTS_ELEMENTS: {
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
// Ascertain whether we have read-only properties or an existing
// getter/setter pair in an arguments elements dictionary backing
// store.
@ -6381,8 +6379,7 @@ void JSObject::SetElementCallback(Handle<JSObject> object,
// Normalize elements to make this operation simple.
bool had_dictionary_elements = object->HasDictionaryElements();
Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
DCHECK(object->HasDictionaryElements() ||
object->HasDictionaryArgumentsElements());
DCHECK(object->HasDictionaryElements() || object->HasSlowArgumentsElements());
// Update the dictionary with the new ACCESSOR_CONSTANT property.
dictionary = SeededNumberDictionary::Set(dictionary, index, structure,
details);
@ -7164,7 +7161,8 @@ Handle<Map> Map::PrepareForDataElement(Handle<Map> map, Handle<Object> value) {
case FAST_ELEMENTS:
case FAST_HOLEY_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_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:
@ -12334,30 +12332,6 @@ void JSObject::EnsureCanContainElements(Handle<JSObject> object,
}
bool JSObject::HasFastArgumentsElements() {
Heap* heap = GetHeap();
if (!elements()->IsFixedArray()) return false;
FixedArray* elements = FixedArray::cast(this->elements());
if (elements->map() != heap->sloppy_arguments_elements_map()) {
return false;
}
FixedArray* arguments = FixedArray::cast(elements->get(1));
return !arguments->IsDictionary();
}
bool JSObject::HasDictionaryArgumentsElements() {
Heap* heap = GetHeap();
if (!elements()->IsFixedArray()) return false;
FixedArray* elements = FixedArray::cast(this->elements());
if (elements->map() != heap->sloppy_arguments_elements_map()) {
return false;
}
FixedArray* arguments = FixedArray::cast(elements->get(1));
return arguments->IsDictionary();
}
ElementsAccessor* JSObject::GetElementsAccessor() {
return ElementsAccessor::ForKind(GetElementsKind());
}
@ -12424,7 +12398,9 @@ bool JSObject::WouldConvertToSlowElements(uint32_t index) {
static ElementsKind BestFittingFastElementsKind(JSObject* object) {
if (object->HasSloppyArgumentsElements()) return SLOPPY_ARGUMENTS_ELEMENTS;
if (object->HasSloppyArgumentsElements()) {
return FAST_SLOPPY_ARGUMENTS_ELEMENTS;
}
DCHECK(object->HasDictionaryElements());
SeededNumberDictionary* dictionary = object->element_dictionary();
ElementsKind kind = FAST_HOLEY_SMI_ELEMENTS;
@ -12491,49 +12467,34 @@ MaybeHandle<Object> JSObject::AddDataElement(Handle<JSObject> object,
ElementsKind kind = object->GetElementsKind();
FixedArrayBase* elements = object->elements();
ElementsKind dictionary_kind = DICTIONARY_ELEMENTS;
if (IsSloppyArgumentsElements(kind)) {
elements = FixedArrayBase::cast(FixedArray::cast(elements)->get(1));
dictionary_kind = SLOW_SLOPPY_ARGUMENTS_ELEMENTS;
}
if (attributes != NONE) {
kind = DICTIONARY_ELEMENTS;
kind = dictionary_kind;
} else if (elements->IsSeededNumberDictionary()) {
kind = ShouldConvertToFastElements(*object,
SeededNumberDictionary::cast(elements),
index, &new_capacity)
? BestFittingFastElementsKind(*object)
: DICTIONARY_ELEMENTS; // Overwrite in case of arguments.
: dictionary_kind; // Overwrite in case of arguments.
} else if (ShouldConvertToSlowElements(
*object, static_cast<uint32_t>(elements->length()), index,
&new_capacity)) {
kind = DICTIONARY_ELEMENTS;
kind = dictionary_kind;
}
if (kind == DICTIONARY_ELEMENTS && object->HasSloppyArgumentsElements()) {
// TODO(verwaest): Distinguish fast/slow sloppy elements in ElementsKind.
Handle<SeededNumberDictionary> dictionary =
elements->IsSeededNumberDictionary()
? handle(SeededNumberDictionary::cast(elements))
: NormalizeElements(object);
PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
Handle<SeededNumberDictionary> new_dictionary =
SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
details);
if (attributes != NONE) new_dictionary->set_requires_slow_elements();
if (*dictionary != *new_dictionary) {
FixedArray::cast(object->elements())->set(1, *new_dictionary);
}
} else {
ElementsKind to = value->OptimalElementsKind();
if (IsHoleyElementsKind(kind) || !object->IsJSArray() ||
index > old_length) {
to = GetHoleyElementsKind(to);
kind = GetHoleyElementsKind(kind);
}
to = IsMoreGeneralElementsKindTransition(kind, to) ? to : kind;
ElementsAccessor* accessor = ElementsAccessor::ForKind(to);
accessor->Add(object, index, value, attributes, new_capacity);
ElementsKind to = value->OptimalElementsKind();
if (IsHoleyElementsKind(kind) || !object->IsJSArray() || index > old_length) {
to = GetHoleyElementsKind(to);
kind = GetHoleyElementsKind(kind);
}
to = IsMoreGeneralElementsKindTransition(kind, to) ? to : kind;
ElementsAccessor* accessor = ElementsAccessor::ForKind(to);
accessor->Add(object, index, value, attributes, new_capacity);
uint32_t new_length = old_length;
Handle<Object> new_length_handle;
@ -12792,7 +12753,8 @@ void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) {
FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements());
FixedArray* backing_store = NULL;
switch (GetElementsKind()) {
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
backing_store_base =
FixedArray::cast(FixedArray::cast(backing_store_base)->get(1));
backing_store = FixedArray::cast(backing_store_base);
@ -13289,7 +13251,8 @@ int JSObject::GetOwnElementKeys(FixedArray* storage,
counter += element_dictionary()->NumberOfElementsFilterAttributes(filter);
break;
}
case SLOPPY_ARGUMENTS_ELEMENTS: {
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
FixedArray* parameter_map = FixedArray::cast(elements());
int mapped_length = parameter_map->length() - 2;
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));

View File

@ -1835,8 +1835,8 @@ class JSObject: public JSReceiver {
inline bool HasFixedFloat32Elements();
inline bool HasFixedFloat64Elements();
bool HasFastArgumentsElements();
bool HasDictionaryArgumentsElements();
inline bool HasFastArgumentsElements();
inline bool HasSlowArgumentsElements();
inline SeededNumberDictionary* element_dictionary(); // Gets slow elements.
// Requires: HasFastElements().
@ -5708,7 +5708,7 @@ class Map: public HeapObject {
}
inline bool has_sloppy_arguments_elements() {
return elements_kind() == SLOPPY_ARGUMENTS_ELEMENTS;
return IsSloppyArgumentsElements(elements_kind());
}
inline bool has_external_array_elements() {
@ -5723,11 +5723,6 @@ class Map: public HeapObject {
return IsDictionaryElementsKind(elements_kind());
}
inline bool has_slow_elements_kind() {
return elements_kind() == DICTIONARY_ELEMENTS
|| elements_kind() == SLOPPY_ARGUMENTS_ELEMENTS;
}
static bool IsValidElementsTransition(ElementsKind from_kind,
ElementsKind to_kind);
@ -6052,7 +6047,8 @@ class Map: public HeapObject {
// Returns the transitioned map for this map with the most generic
// elements_kind that's found in |candidates|, or null handle if no match is
// found at all.
Handle<Map> FindTransitionedMap(MapHandleList* candidates);
static Handle<Map> FindTransitionedMap(Handle<Map> map,
MapHandleList* candidates);
bool CanTransition() {
// Only JSObject and subtypes have map transitions and back pointers.

View File

@ -1792,7 +1792,7 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
const int kNormalOffset =
Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX);
const int kAliasedOffset =
Context::SlotOffset(Context::ALIASED_ARGUMENTS_MAP_INDEX);
Context::SlotOffset(Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX);
__ LoadP(r7,
MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));

View File

@ -3360,7 +3360,8 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
case FAST_ELEMENTS:
case FAST_SMI_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}
@ -4589,7 +4590,8 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
case FAST_HOLEY_ELEMENTS:
case FAST_HOLEY_SMI_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}

View File

@ -295,7 +295,8 @@ static uint32_t EstimateElementCount(Handle<JSArray> array) {
}
break;
}
case SLOPPY_ARGUMENTS_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:
@ -436,7 +437,8 @@ static void CollectElementIndices(Handle<JSObject> object, uint32_t range,
if (length == range) return; // All indices accounted for already.
break;
}
case SLOPPY_ARGUMENTS_ELEMENTS: {
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
MaybeHandle<Object> length_obj =
Object::GetProperty(object, isolate->factory()->length_string());
double length_num = length_obj.ToHandleChecked()->Number();
@ -706,7 +708,8 @@ static bool IterateElements(Isolate* isolate, Handle<JSObject> receiver,
isolate, receiver, false, false, visitor);
break;
}
case SLOPPY_ARGUMENTS_ELEMENTS: {
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: {
for (uint32_t index = 0; index < length; index++) {
HandleScope loop_scope(isolate);
Handle<Object> element;

View File

@ -383,11 +383,7 @@ static Handle<JSObject> NewSloppyArguments(Isolate* isolate,
Handle<FixedArray> parameter_map =
isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
parameter_map->set_map(isolate->heap()->sloppy_arguments_elements_map());
Handle<Map> map = Map::Copy(handle(result->map()), "NewSloppyArguments");
map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
result->set_map(*map);
result->set_map(isolate->native_context()->fast_aliased_arguments_map());
result->set_elements(*parameter_map);
// Store the context and the arguments array at the beginning of the

View File

@ -674,7 +674,7 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
__ movp(rdi, Operand(rdi, Context::SlotOffset(kIndex)));
__ jmp(&instantiate, Label::kNear);
const int kAliasedIndex = Context::ALIASED_ARGUMENTS_MAP_INDEX;
const int kAliasedIndex = Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX;
__ bind(&has_mapped_parameters);
__ movp(rdi, Operand(rdi, Context::SlotOffset(kAliasedIndex)));
__ bind(&instantiate);

View File

@ -3138,7 +3138,8 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
case FAST_HOLEY_SMI_ELEMENTS:
case FAST_HOLEY_DOUBLE_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}
@ -4360,7 +4361,8 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
case FAST_HOLEY_SMI_ELEMENTS:
case FAST_HOLEY_DOUBLE_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}

View File

@ -580,9 +580,8 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
__ jmp(&instantiate, Label::kNear);
__ bind(&has_mapped_parameters);
__ mov(
edi,
Operand(edi, Context::SlotOffset(Context::ALIASED_ARGUMENTS_MAP_INDEX)));
__ mov(edi, Operand(edi, Context::SlotOffset(
Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)));
__ bind(&instantiate);
// eax = address of new object (tagged)

View File

@ -3364,7 +3364,8 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
case FAST_HOLEY_ELEMENTS:
case FAST_HOLEY_DOUBLE_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}
@ -4618,7 +4619,8 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
case FAST_HOLEY_ELEMENTS:
case FAST_HOLEY_DOUBLE_ELEMENTS:
case DICTIONARY_ELEMENTS:
case SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
UNREACHABLE();
break;
}