Commit e7e77bb2 authored by Daniel Clifford's avatar Daniel Clifford Committed by Commit Bot

Port SloppyArgumentsElements to Torque

Change-Id: I092c0d70bf517b4c714f5958b188d54030dd9774
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1932838
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67954}
parent f34771f7
......@@ -36,21 +36,18 @@ macro HandleFastAliasedSloppyArgumentsSlice(
const sloppyElements: SloppyArgumentsElements =
Cast<SloppyArgumentsElements>(args.elements) otherwise Bailout;
const sloppyElementsLength: Smi = sloppyElements.length;
const parameterMapLength: Smi =
sloppyElementsLength - kSloppyArgumentsParameterMapStart;
const parameterMapLength: Smi = sloppyElements.length;
// Check to make sure that the extraction will not access outside the
// defined arguments
const end: Smi = start + count;
const unmappedElements: FixedArray =
Cast<FixedArray>(sloppyElements.objects[kSloppyArgumentsArgumentsIndex])
Cast<FixedArray>(sloppyElements.arguments)
otherwise Bailout;
const unmappedElementsLength: Smi = unmappedElements.length;
if (SmiAbove(end, unmappedElementsLength)) goto Bailout;
const argumentsContext: Context =
UnsafeCast<Context>(sloppyElements.objects[kSloppyArgumentsContextIndex]);
const argumentsContext: Context = sloppyElements.context;
const arrayMap: Map =
LoadJSArrayElementsMap(ElementsKind::HOLEY_ELEMENTS, context);
......@@ -63,8 +60,7 @@ macro HandleFastAliasedSloppyArgumentsSlice(
// Fill in the part of the result that map to context-mapped parameters.
for (let current: Smi = start; current < to; ++current) {
const e: Object =
sloppyElements.objects[current + kSloppyArgumentsParameterMapStart];
const e: Object = sloppyElements.mapped_entries[current];
const newElement = UnsafeCast<(JSAny | TheHole)>(
e != TheHole ? argumentsContext[UnsafeCast<Smi>(e)] :
unmappedElements.objects[current]);
......
......@@ -365,12 +365,6 @@ const kMaxRegularHeapObjectSize: constexpr int31
const kMaxNewSpaceFixedArrayElements: constexpr int31
generates 'FixedArray::kMaxRegularLength';
const kSloppyArgumentsArgumentsIndex: constexpr int31
generates 'SloppyArgumentsElements::kArgumentsIndex';
const kSloppyArgumentsContextIndex: constexpr int31
generates 'SloppyArgumentsElements::kContextIndex';
const kSloppyArgumentsParameterMapStart: constexpr int31
generates 'SloppyArgumentsElements::kParameterMapStart';
extern enum PrimitiveType { kString, kBoolean, kSymbol, kNumber }
......@@ -999,7 +993,6 @@ extern macro EmptyFixedArrayConstant(): EmptyFixedArray;
extern macro PromiseCapabilityMapConstant(): Map;
extern macro OneByteStringMapConstant(): Map;
extern macro StringMapConstant(): Map;
extern macro SloppyArgumentsElementsMapConstant(): Map;
const kFixedArrayMap: Map = FixedArrayMapConstant();
const kFixedDoubleArrayMap: Map = FixedDoubleArrayMapConstant();
......@@ -1011,7 +1004,6 @@ const kPromiseCapabilityMap: Map = PromiseCapabilityMapConstant();
const kOneByteStringMap: Map = OneByteStringMapConstant();
// The map of a non-internalized internal SeqTwoByteString.
const kStringMap: Map = StringMapConstant();
const kSloppyArgumentsElementsMap: Map = SloppyArgumentsElementsMapConstant();
extern macro IsPrototypeInitialArrayPrototype(implicit context: Context)(Map):
bool;
......
......@@ -9,6 +9,7 @@
#include "src/ic/ic.h"
#include "src/ic/keyed-store-generic.h"
#include "src/objects/objects-inl.h"
#include "torque-generated/exported-macros-assembler-tq.h"
namespace v8 {
namespace internal {
......@@ -78,37 +79,11 @@ TNode<Object> HandlerBuiltinsAssembler::EmitKeyedSloppyArguments(
TNode<JSObject> receiver, TNode<Object> tagged_key,
base::Optional<TNode<Object>> value, Label* bailout,
ArgumentsAccessMode access_mode) {
// Mapped arguments are actual arguments. Unmapped arguments are values added
// to the arguments object after it was created for the call. Mapped arguments
// are stored in the context at indexes given by elements[key + 2]. Unmapped
// arguments are stored as regular indexed properties in the arguments array,
// held at elements[1]. See NewSloppyArguments() in runtime.cc for a detailed
// look at argument object construction.
//
// The sloppy arguments elements array has a special format:
//
// 0: context
// 1: unmapped arguments array
// 2: mapped_index0,
// 3: mapped_index1,
// ...
//
// length is 2 + min(number_of_actual_arguments, number_of_formal_arguments).
// If key + 2 >= elements.length then attempt to look in the unmapped
// arguments array (given by elements[1]) and return the value at key, missing
// to the runtime if the unmapped arguments array is not a fixed array or if
// key >= unmapped_arguments_array.length.
//
// Otherwise, t = elements[key + 2]. If t is the hole, then look up the value
// in the unmapped arguments array, as described above. Otherwise, t is a Smi
// index into the context array given at elements[0]. Return the value at
// context[t].
GotoIfNot(TaggedIsSmi(tagged_key), bailout);
TNode<IntPtrT> key = SmiUntag(CAST(tagged_key));
GotoIf(IntPtrLessThan(key, IntPtrConstant(0)), bailout);
TNode<FixedArray> elements = CAST(LoadElements(receiver));
TNode<SloppyArgumentsElements> elements = CAST(LoadElements(receiver));
TNode<IntPtrT> elements_length = LoadAndUntagFixedArrayBaseLength(elements);
TVARIABLE(Object, var_result);
......@@ -119,20 +94,18 @@ TNode<Object> HandlerBuiltinsAssembler::EmitKeyedSloppyArguments(
access_mode == ArgumentsAccessMode::kHas);
}
Label if_mapped(this), if_unmapped(this), end(this, &var_result);
TNode<IntPtrT> intptr_two = IntPtrConstant(2);
TNode<IntPtrT> adjusted_length = IntPtrSub(elements_length, intptr_two);
GotoIf(UintPtrGreaterThanOrEqual(key, adjusted_length), &if_unmapped);
GotoIf(UintPtrGreaterThanOrEqual(key, elements_length), &if_unmapped);
TNode<Object> mapped_index =
LoadFixedArrayElement(elements, IntPtrAdd(key, intptr_two));
LoadSloppyArgumentsElementsMappedEntries(elements, key);
Branch(TaggedEqual(mapped_index, TheHoleConstant()), &if_unmapped,
&if_mapped);
BIND(&if_mapped);
{
TNode<IntPtrT> mapped_index_intptr = SmiUntag(CAST(mapped_index));
TNode<Context> the_context = CAST(LoadFixedArrayElement(elements, 0));
TNode<Context> the_context = LoadSloppyArgumentsElementsContext(elements);
if (access_mode == ArgumentsAccessMode::kLoad) {
TNode<Object> result =
LoadContextElement(the_context, mapped_index_intptr);
......@@ -151,7 +124,7 @@ TNode<Object> HandlerBuiltinsAssembler::EmitKeyedSloppyArguments(
BIND(&if_unmapped);
{
TNode<HeapObject> backing_store_ho =
CAST(LoadFixedArrayElement(elements, 1));
LoadSloppyArgumentsElementsArguments(elements);
GotoIf(TaggedNotEqual(LoadMap(backing_store_ho), FixedArrayMapConstant()),
bailout);
TNode<FixedArray> backing_store = CAST(backing_store_ho);
......
......@@ -195,8 +195,6 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
V(resolve_string, resolve_string, ResolveString) \
V(return_string, return_string, ReturnString) \
V(SharedFunctionInfoMap, shared_function_info_map, SharedFunctionInfoMap) \
V(SloppyArgumentsElementsMap, sloppy_arguments_elements_map, \
SloppyArgumentsElementsMap) \
V(SmallOrderedHashSetMap, small_ordered_hash_set_map, \
SmallOrderedHashSetMap) \
V(SmallOrderedHashMapMap, small_ordered_hash_map_map, \
......
......@@ -17,6 +17,7 @@
#include "src/objects/objects-inl.h"
#include "src/objects/ordered-hash-table.h"
#include "src/objects/source-text-module.h"
#include "torque-generated/exported-class-definitions-tq.h"
namespace v8 {
namespace internal {
......@@ -529,6 +530,26 @@ FieldAccess AccessBuilder::ForFixedArrayLength() {
return access;
}
// static
FieldAccess AccessBuilder::ForSloppyArgumentsElementsContext() {
FieldAccess access = {
kTaggedBase, SloppyArgumentsElements::kContextOffset,
MaybeHandle<Name>(), MaybeHandle<Map>(),
Type::Any(), MachineType::TaggedPointer(),
kPointerWriteBarrier};
return access;
}
// static
FieldAccess AccessBuilder::ForSloppyArgumentsElementsArguments() {
FieldAccess access = {
kTaggedBase, SloppyArgumentsElements::kArgumentsOffset,
MaybeHandle<Name>(), MaybeHandle<Map>(),
Type::Any(), MachineType::TaggedPointer(),
kPointerWriteBarrier};
return access;
}
// static
FieldAccess AccessBuilder::ForPropertyArrayLengthAndHash() {
FieldAccess access = {
......@@ -867,6 +888,14 @@ ElementAccess AccessBuilder::ForFixedArrayElement() {
}
// static
ElementAccess AccessBuilder::ForSloppyArgumentsElementsMappedEntry() {
ElementAccess access = {
kTaggedBase, SloppyArgumentsElements::kMappedEntriesOffset, Type::Any(),
MachineType::AnyTagged(), kFullWriteBarrier};
return access;
}
// statics
ElementAccess AccessBuilder::ForFixedArrayElement(
ElementsKind kind, LoadSensitivity load_sensitivity) {
ElementAccess access = {kTaggedBase, FixedArray::kHeaderSize,
......
......@@ -179,6 +179,12 @@ class V8_EXPORT_PRIVATE AccessBuilder final
// Provides access to FixedArray::length() field.
static FieldAccess ForFixedArrayLength();
// Provides access to SloppyArgumentsElements::context() field.
static FieldAccess ForSloppyArgumentsElementsContext();
// Provides access to SloppyArgumentsElements::arguments() field.
static FieldAccess ForSloppyArgumentsElementsArguments();
// Provides access to PropertyArray::length() field.
static FieldAccess ForPropertyArrayLengthAndHash();
......@@ -283,6 +289,9 @@ class V8_EXPORT_PRIVATE AccessBuilder final
ElementsKind kind,
LoadSensitivity load_sensitivity = LoadSensitivity::kUnsafe);
// Provides access to SloppyArgumentsElements elements.
static ElementAccess ForSloppyArgumentsElementsMappedEntry();
// Provides access to stack arguments
static ElementAccess ForStackArgument();
......
......@@ -5,10 +5,11 @@
#ifndef V8_COMPILER_ALLOCATION_BUILDER_INL_H_
#define V8_COMPILER_ALLOCATION_BUILDER_INL_H_
#include "src/compiler/allocation-builder.h"
#include "src/compiler/access-builder.h"
#include "src/compiler/allocation-builder.h"
#include "src/objects/map-inl.h"
#include "torque-generated/exported-class-definitions-tq-inl.h"
#include "torque-generated/exported-class-definitions-tq.h"
namespace v8 {
namespace internal {
......@@ -40,6 +41,14 @@ void AllocationBuilder::AllocateArray(int length, MapRef map,
Store(AccessBuilder::ForFixedArrayLength(), jsgraph()->Constant(length));
}
void AllocationBuilder::AllocateSloppyArgumentElements(
int length, MapRef map, AllocationType allocation) {
int size = SloppyArgumentsElements::SizeFor(length);
Allocate(size, allocation, Type::OtherInternal());
Store(AccessBuilder::ForMap(), map);
Store(AccessBuilder::ForFixedArrayLength(), jsgraph()->Constant(length));
}
} // namespace compiler
} // namespace internal
} // namespace v8
......
......@@ -55,6 +55,11 @@ class AllocationBuilder final {
inline void AllocateArray(int length, MapRef map,
AllocationType allocation = AllocationType::kYoung);
// Compound allocation of a SloppyArgumentsElements
inline void AllocateSloppyArgumentElements(
int length, MapRef map,
AllocationType allocation = AllocationType::kYoung);
// Compound store of a constant into a field.
void Store(const FieldAccess& access, const ObjectRef& value) {
Store(access, jsgraph()->Constant(value));
......
......@@ -28,6 +28,7 @@
#include "src/objects/js-regexp-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/template-objects.h"
#include "torque-generated/exported-class-definitions-tq.h"
namespace v8 {
namespace internal {
......@@ -1507,16 +1508,15 @@ Node* JSCreateLowering::AllocateAliasedArguments(
// Actually allocate the backing store.
AllocationBuilder a(jsgraph(), arguments, control);
a.AllocateArray(mapped_count + 2,
a.AllocateSloppyArgumentElements(
mapped_count,
MapRef(broker(), factory()->sloppy_arguments_elements_map()));
a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(0),
context);
a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(1),
arguments);
a.Store(AccessBuilder::ForSloppyArgumentsElementsContext(), context);
a.Store(AccessBuilder::ForSloppyArgumentsElementsArguments(), arguments);
for (int i = 0; i < mapped_count; ++i) {
int idx = shared.context_header_size() + parameter_count - 1 - i;
a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i + 2),
jsgraph()->Constant(idx));
a.Store(AccessBuilder::ForSloppyArgumentsElementsMappedEntry(),
jsgraph()->Constant(i), jsgraph()->Constant(idx));
}
return a.Finish();
}
......@@ -1553,12 +1553,11 @@ Node* JSCreateLowering::AllocateAliasedArguments(
// Actually allocate the backing store.
AllocationBuilder a(jsgraph(), effect, control);
a.AllocateArray(mapped_count + 2,
a.AllocateSloppyArgumentElements(
mapped_count,
MapRef(broker(), factory()->sloppy_arguments_elements_map()));
a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(0),
context);
a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(1),
arguments);
a.Store(AccessBuilder::ForSloppyArgumentsElementsContext(), context);
a.Store(AccessBuilder::ForSloppyArgumentsElementsArguments(), arguments);
for (int i = 0; i < mapped_count; ++i) {
int idx = shared.context_header_size() + parameter_count - 1 - i;
Node* value = graph()->NewNode(
......@@ -1566,8 +1565,8 @@ Node* JSCreateLowering::AllocateAliasedArguments(
graph()->NewNode(simplified()->NumberLessThan(), jsgraph()->Constant(i),
arguments_length),
jsgraph()->Constant(idx), jsgraph()->TheHoleConstant());
a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i + 2),
value);
a.Store(AccessBuilder::ForSloppyArgumentsElementsMappedEntry(),
jsgraph()->Constant(i), value);
}
return a.Finish();
}
......
......@@ -26,6 +26,7 @@
#include "src/objects/heap-number-inl.h"
#include "src/objects/smi.h"
#include "src/tracing/trace-event.h"
#include "torque-generated/exported-class-definitions-tq.h"
// Has to be the last include (doesn't have include guards)
#include "src/objects/object-macros.h"
......@@ -3473,6 +3474,7 @@ void TranslatedState::InitializeCapturedObjectAt(
case STRING_TABLE_TYPE:
case PROPERTY_ARRAY_TYPE:
case SCRIPT_CONTEXT_TABLE_TYPE:
case SLOPPY_ARGUMENTS_ELEMENTS_TYPE:
InitializeObjectWithTaggedFieldsAt(frame, &value_index, slot, map,
no_allocation);
break;
......@@ -3633,6 +3635,19 @@ void TranslatedState::EnsureCapturedObjectAllocatedAt(
&value_index, worklist);
}
case SLOPPY_ARGUMENTS_ELEMENTS_TYPE: {
// Verify that the arguments size is correct.
Smi args_length = Smi::cast(frame->values_[value_index].GetRawValue());
int args_size = SloppyArgumentsElements::SizeFor(args_length.value());
CHECK_EQ(args_size, slot->GetChildrenCount() * kTaggedSize);
slot->set_storage(AllocateStorageFor(slot));
// Make sure all the remaining children (after the map) are allocated.
return EnsureChildrenAllocated(slot->GetChildrenCount() - 1, frame,
&value_index, worklist);
}
case PROPERTY_ARRAY_TYPE: {
// Check we have the right size.
int length_or_hash =
......
......@@ -326,6 +326,11 @@ void VerifyJSObjectElements(Isolate* isolate, JSObject object) {
return;
}
if (object.HasSloppyArgumentsElements()) {
CHECK(object.elements().IsSloppyArgumentsElements());
return;
}
FixedArray elements = FixedArray::cast(object.elements());
if (object.HasSmiElements()) {
// We might have a partially initialized backing store, in which case we
......@@ -626,39 +631,15 @@ void TransitionArray::TransitionArrayVerify(Isolate* isolate) {
CHECK_LE(LengthFor(number_of_transitions()), length());
}
void JSArgumentsObject::JSArgumentsObjectVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::JSArgumentsObjectVerify(*this, isolate);
if (IsSloppyArgumentsElementsKind(GetElementsKind())) {
SloppyArgumentsElements::cast(elements())
.SloppyArgumentsElementsVerify(isolate, *this);
}
if (isolate->IsInAnyContext(map(), Context::SLOPPY_ARGUMENTS_MAP_INDEX) ||
isolate->IsInAnyContext(map(),
Context::SLOW_ALIASED_ARGUMENTS_MAP_INDEX) ||
isolate->IsInAnyContext(map(),
Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)) {
VerifyObjectField(isolate, JSSloppyArgumentsObject::kLengthOffset);
VerifyObjectField(isolate, JSSloppyArgumentsObject::kCalleeOffset);
} else if (isolate->IsInAnyContext(map(),
Context::STRICT_ARGUMENTS_MAP_INDEX)) {
VerifyObjectField(isolate, JSStrictArgumentsObject::kLengthOffset);
}
}
void SloppyArgumentsElements::SloppyArgumentsElementsVerify(Isolate* isolate,
namespace {
void SloppyArgumentsElementsVerify(Isolate* isolate,
SloppyArgumentsElements elements,
JSObject holder) {
FixedArrayVerify(isolate);
// Abort verification if only partially initialized (can't use arguments()
// getter because it does FixedArray::cast()).
if (get(kArgumentsIndex).IsUndefined(isolate)) return;
elements.SloppyArgumentsElementsVerify(isolate);
ElementsKind kind = holder.GetElementsKind();
bool is_fast = kind == FAST_SLOPPY_ARGUMENTS_ELEMENTS;
CHECK(IsFixedArray());
CHECK_GE(length(), 2);
CHECK_EQ(map(), ReadOnlyRoots(isolate).sloppy_arguments_elements_map());
Context context_object = context();
FixedArray arg_elements = FixedArray::cast(arguments());
Context context_object = elements.context();
FixedArray arg_elements = elements.arguments();
if (arg_elements.length() == 0) {
CHECK(arg_elements == ReadOnlyRoots(isolate).empty_fixed_array());
return;
......@@ -674,7 +655,7 @@ void SloppyArgumentsElements::SloppyArgumentsElementsVerify(Isolate* isolate,
for (int i = 0; i < nofMappedParameters; i++) {
// Verify that each context-mapped argument is either the hole or a valid
// Smi within context length range.
Object mapped = get_mapped_entry(i);
Object mapped = elements.mapped_entries(i);
if (mapped.IsTheHole(isolate)) {
// Slow sloppy arguments can be holey.
if (!is_fast) continue;
......@@ -698,6 +679,26 @@ void SloppyArgumentsElements::SloppyArgumentsElementsVerify(Isolate* isolate,
CHECK_LE(maxMappedIndex, context_object.length());
CHECK_LE(maxMappedIndex, arg_elements.length());
}
} // namespace
void JSArgumentsObject::JSArgumentsObjectVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::JSArgumentsObjectVerify(*this, isolate);
if (IsSloppyArgumentsElementsKind(GetElementsKind())) {
SloppyArgumentsElementsVerify(
isolate, SloppyArgumentsElements::cast(elements()), *this);
}
if (isolate->IsInAnyContext(map(), Context::SLOPPY_ARGUMENTS_MAP_INDEX) ||
isolate->IsInAnyContext(map(),
Context::SLOW_ALIASED_ARGUMENTS_MAP_INDEX) ||
isolate->IsInAnyContext(map(),
Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX)) {
VerifyObjectField(isolate, JSSloppyArgumentsObject::kLengthOffset);
VerifyObjectField(isolate, JSSloppyArgumentsObject::kCalleeOffset);
} else if (isolate->IsInAnyContext(map(),
Context::STRICT_ARGUMENTS_MAP_INDEX)) {
VerifyObjectField(isolate, JSStrictArgumentsObject::kLengthOffset);
}
}
void JSAsyncFunctionObject::JSAsyncFunctionObjectVerify(Isolate* isolate) {
TorqueGeneratedClassVerifiers::JSAsyncFunctionObjectVerify(*this, isolate);
......
......@@ -436,11 +436,9 @@ void PrintSloppyArgumentElements(std::ostream& os, ElementsKind kind,
os << "\n 0: context: " << Brief(elements.context())
<< "\n 1: arguments_store: " << Brief(arguments_store)
<< "\n parameter to context slot map:";
for (uint32_t i = 0; i < elements.parameter_map_length(); i++) {
uint32_t raw_index = i + SloppyArgumentsElements::kParameterMapStart;
Object mapped_entry = elements.get_mapped_entry(i);
os << "\n " << raw_index << ": param(" << i
<< "): " << Brief(mapped_entry);
for (int i = 0; i < elements.length(); i++) {
Object mapped_entry = elements.mapped_entries(i);
os << "\n " << i << ": param(" << i << "): " << Brief(mapped_entry);
if (mapped_entry.IsTheHole()) {
os << " in the arguments_store[" << i << "]";
} else {
......
......@@ -839,7 +839,6 @@ void ObjectStatsCollectorImpl::RecordObjectStats(HeapObject obj,
bool ObjectStatsCollectorImpl::CanRecordFixedArray(FixedArrayBase array) {
ReadOnlyRoots roots(heap_);
return array != roots.empty_fixed_array() &&
array != roots.empty_sloppy_arguments_elements() &&
array != roots.empty_slow_element_dictionary() &&
array != roots.empty_property_dictionary();
}
......
......@@ -429,8 +429,6 @@ bool Heap::CreateInitialMaps() {
TORQUE_INTERNAL_VARSIZE_INSTANCE_TYPE_LIST(TORQUE_ALLOCATE_VARSIZE_MAP);
#undef TORQUE_ALLOCATE_VARSIZE_MAP
ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, sloppy_arguments_elements)
ALLOCATE_VARSIZE_MAP(CODE_TYPE, code)
ALLOCATE_MAP(CELL_TYPE, Cell::kSize, cell);
......@@ -784,14 +782,6 @@ void Heap::CreateInitialObjects() {
factory->NewManyClosuresCell(factory->undefined_value());
set_many_closures_cell(*many_closures_cell);
{
Handle<FixedArray> empty_sloppy_arguments_elements =
factory->NewFixedArray(2, AllocationType::kReadOnly);
empty_sloppy_arguments_elements->set_map_after_allocation(
roots.sloppy_arguments_elements_map(), SKIP_WRITE_BARRIER);
set_empty_sloppy_arguments_elements(*empty_sloppy_arguments_elements);
}
set_detached_contexts(roots.empty_weak_array_list());
set_retaining_path_targets(roots.empty_weak_array_list());
......
......@@ -5,9 +5,8 @@
#ifndef V8_OBJECTS_ARGUMENTS_INL_H_
#define V8_OBJECTS_ARGUMENTS_INL_H_
#include "src/objects/arguments.h"
#include "src/execution/isolate-inl.h"
#include "src/objects/arguments.h"
#include "src/objects/contexts-inl.h"
#include "src/objects/fixed-array-inl.h"
#include "src/objects/objects-inl.h"
......@@ -18,38 +17,9 @@
namespace v8 {
namespace internal {
OBJECT_CONSTRUCTORS_IMPL(SloppyArgumentsElements, FixedArray)
TQ_OBJECT_CONSTRUCTORS_IMPL(JSArgumentsObject)
TQ_OBJECT_CONSTRUCTORS_IMPL(AliasedArgumentsEntry)
CAST_ACCESSOR(SloppyArgumentsElements)
DEF_GETTER(SloppyArgumentsElements, context, Context) {
return TaggedField<Context>::load(isolate, *this,
OffsetOfElementAt(kContextIndex));
}
DEF_GETTER(SloppyArgumentsElements, arguments, FixedArray) {
return TaggedField<FixedArray>::load(isolate, *this,
OffsetOfElementAt(kArgumentsIndex));
}
void SloppyArgumentsElements::set_arguments(FixedArray arguments) {
set(kArgumentsIndex, arguments);
}
uint32_t SloppyArgumentsElements::parameter_map_length() {
return length() - kParameterMapStart;
}
Object SloppyArgumentsElements::get_mapped_entry(uint32_t entry) {
return get(entry + kParameterMapStart);
}
void SloppyArgumentsElements::set_mapped_entry(uint32_t entry, Object object) {
set(entry + kParameterMapStart, object);
}
} // namespace internal
} // namespace v8
......
......@@ -58,49 +58,6 @@ class JSStrictArgumentsObject : public JSArgumentsObject {
DISALLOW_IMPLICIT_CONSTRUCTORS(JSStrictArgumentsObject);
};
// Helper class to access FAST_ and SLOW_SLOPPY_ARGUMENTS_ELEMENTS
//
// +---+-----------------------+
// | 0 | Context context |
// +---------------------------+
// | 1 | FixedArray arguments +----+ HOLEY_ELEMENTS
// +---------------------------+ v-----+-----------+
// | 2 | Object param_1_map | | 0 | the_hole |
// |...| ... | | ... | ... |
// |n+1| Object param_n_map | | n-1 | the_hole |
// +---------------------------+ | n | element_1 |
// | ... | ... |
// |n+m-1| element_m |
// +-----------------+
//
// Parameter maps give the index into the provided context. If a map entry is
// the_hole it means that the given entry has been deleted from the arguments
// object.
// The arguments backing store kind depends on the ElementsKind of the outer
// JSArgumentsObject:
// - FAST_SLOPPY_ARGUMENTS_ELEMENTS: HOLEY_ELEMENTS
// - SLOW_SLOPPY_ARGUMENTS_ELEMENTS: DICTIONARY_ELEMENTS
class SloppyArgumentsElements : public FixedArray {
public:
static const int kContextIndex = 0;
static const int kArgumentsIndex = 1;
static const uint32_t kParameterMapStart = 2;
DECL_GETTER(context, Context)
DECL_GETTER(arguments, FixedArray)
inline void set_arguments(FixedArray arguments);
inline uint32_t parameter_map_length();
inline Object get_mapped_entry(uint32_t entry);
inline void set_mapped_entry(uint32_t entry, Object object);
DECL_CAST(SloppyArgumentsElements)
#ifdef VERIFY_HEAP
void SloppyArgumentsElementsVerify(Isolate* isolate, JSObject holder);
#endif
OBJECT_CONSTRUCTORS(SloppyArgumentsElements, FixedArray);
};
// Representation of a slow alias as part of a sloppy arguments objects.
// For fast aliases (if HasSloppyArgumentsElements()):
// - the parameter map contains an index into the context
......
......@@ -26,7 +26,69 @@ extern shape JSStrictArgumentsObject extends JSArgumentsObject {
length: JSAny;
}
type SloppyArgumentsElements extends FixedArray;
// Helper class to access FAST_ and SLOW_SLOPPY_ARGUMENTS_ELEMENTS, dividing
// arguments into two types for a given SloppyArgumentsElements object:
// mapped and unmapped.
//
// For clarity SloppyArgumentsElements fields are qualified with "elements."
// below.
//
// Mapped arguments are actual arguments. Unmapped arguments are values added
// to the arguments object after it was created for the call. Mapped arguments
// are stored in the context at indexes given by elements.mapped_entries[key].
// Unmapped arguments are stored as regular indexed properties in the arguments
// array which can be accessed from elements.arguments.
//
// elements.length is min(number_of_actual_arguments,
// number_of_formal_arguments) for a concrete call to a function.
//
// Once a SloppyArgumentsElements is generated, lookup of an argument with index
// |key| in |elements| works as follows:
//
// If key >= elements.length then attempt to look in the unmapped arguments
// array and return the value at key, missing to the runtime if the unmapped
// arguments array is not a fixed array or if key >= elements.arguments.length.
//
// Otherwise, t = elements.mapped_entries[key]. If t is the hole, then the
// entry has been deleted fron the arguments object, and value is looked up in
// the unmapped arguments array, as described above. Otherwise, t is a Smi
// index into the context array specified at elements.context, and the return
// value is elements.context[t].
//
// A graphic representation of a SloppyArgumentsElements object and a
// corresponding unmapped arguments FixedArray:
//
// SloppyArgumentsElements
// +---+-----------------------+
// | Context context |
// +---------------------------+
// | FixedArray arguments +----+ HOLEY_ELEMENTS
// +---------------------------+ v-----+-----------+
// | 0 | Object mapped_entries | | 0 | the_hole |
// |...| ... | | ... | ... |
// |n-1| Object mapped_entries | | n-1 | the_hole |
// +---------------------------+ | n | element_1 |
// | ... | ... |
// |n+m-1| element_m |
// +-----------------+
//
// The elements.arguments backing store kind depends on the ElementsKind of
// the outer JSArgumentsObject:
// - FAST_SLOPPY_ARGUMENTS_ELEMENTS: HOLEY_ELEMENTS
// - SLOW_SLOPPY_ARGUMENTS_ELEMENTS: DICTIONARY_ELEMENTS
@export
class SloppyArgumentsElements extends FixedArrayBase {
context: Context;
arguments: FixedArray;
mapped_entries[length]: Smi|TheHole;
}
macro NewSloppyArgumentsElements<Iterator: type>(
length: Smi, context: Context, arguments: FixedArray,
it: Iterator): SloppyArgumentsElements {
return new
SloppyArgumentsElements{length, context, arguments, mapped_entries: ...it};
}
@generateCppClass
@generatePrint
......@@ -49,7 +111,7 @@ macro NewJSStrictArgumentsObject(implicit context: Context)(
}
macro NewJSSloppyArgumentsObject(implicit context: Context)(
elements: FixedArray, callee: JSFunction): JSSloppyArgumentsObject {
elements: FixedArrayBase, callee: JSFunction): JSSloppyArgumentsObject {
const map = GetSloppyArgumentsMap();
return new JSSloppyArgumentsObject{
map,
......@@ -61,7 +123,7 @@ macro NewJSSloppyArgumentsObject(implicit context: Context)(
}
macro NewJSFastAliasedArgumentsObject(implicit context: Context)(
elements: FixedArray, length: Smi,
elements: FixedArrayBase, length: Smi,
callee: JSFunction): JSSloppyArgumentsObject {
// TODO(danno): FastAliasedArguments should really be a type for itself
const map = GetFastAliasedArgumentsMap();
......@@ -75,28 +137,17 @@ macro NewJSFastAliasedArgumentsObject(implicit context: Context)(
}
struct ParameterMapIterator {
macro Next(): Object labels NoMore {
const currentMapSlotCopy = this.currentMapSlot++;
if (currentMapSlotCopy > 1) {
macro Next(): Smi labels NoMore {
if (this.currentIndex == this.endInterationIndex) goto NoMore;
this.currentIndex--;
return Convert<Smi>(this.currentIndex);
} else if (currentMapSlotCopy == 0) {
return this.context;
} else {
assert(currentMapSlotCopy == 1);
return this.elements;
}
}
const context: Context;
const elements: FixedArray;
currentIndex: intptr;
const endInterationIndex: intptr;
currentMapSlot: intptr;
}
macro NewParameterMapIterator(
context: Context, elements: FixedArray, formalParameterCount: intptr,
context: Context, formalParameterCount: intptr,
mappedCount: intptr): ParameterMapIterator {
const flags = context.scope_info.flags;
let contextHeaderSize: intptr = MIN_CONTEXT_SLOTS;
......@@ -112,11 +163,8 @@ macro NewParameterMapIterator(
const afterLastContextIndex = contextHeaderSize + formalParameterCount;
const firstContextIndex = afterLastContextIndex - mappedCount;
return ParameterMapIterator{
context,
elements,
currentIndex: afterLastContextIndex,
endInterationIndex: firstContextIndex,
currentMapSlot: 0
endInterationIndex: firstContextIndex
};
}
......@@ -188,17 +236,16 @@ macro NewSloppyArguments(implicit context: Context)(
const mappedCount = IntPtrMin(formalParameterCount, argumentCount);
const it = NewParameterValueIterator(mappedCount, arguments);
const parameterValues = NewFixedArray(argumentCount, it);
let paramIter = NewParameterMapIterator(
context, parameterValues, formalParameterCount, mappedCount);
const elementsLength =
Convert<Smi>(mappedCount + kSloppyArgumentsParameterMapStart);
const map = kSloppyArgumentsElementsMap;
const elements = new
FixedArray{map, length: elementsLength, objects: ...paramIter};
let paramIter =
NewParameterMapIterator(context, formalParameterCount, mappedCount);
const elementsLength = Convert<Smi>(mappedCount);
const elements = NewSloppyArgumentsElements(
elementsLength, context, parameterValues, paramIter);
const length = Convert<Smi>(argumentCount);
return NewJSFastAliasedArgumentsObject(elements, length, callee);
}
}
} // namespace arguments
@export
macro EmitFastNewAllArguments(implicit context: Context)(
......
......@@ -22,6 +22,8 @@
#include "src/objects/slots-atomic-inl.h"
#include "src/objects/slots.h"
#include "src/utils/utils.h"
#include "torque-generated/exported-class-definitions-tq-inl.h"
#include "torque-generated/exported-class-definitions-tq.h"
// Each concrete ElementsAccessor can handle exactly one ElementsKind,
// several abstract ElementsAccessor classes are used to allow sharing
......@@ -3882,11 +3884,11 @@ class SloppyArgumentsElementsAccessor
InternalIndex entry) {
Handle<SloppyArgumentsElements> elements(
SloppyArgumentsElements::cast(parameters), isolate);
uint32_t length = elements->parameter_map_length();
uint32_t length = elements->length();
if (entry.as_uint32() < length) {
// Read context mapped entry.
DisallowHeapAllocation no_gc;
Object probe = elements->get_mapped_entry(entry.as_uint32());
Object probe = elements->mapped_entries(entry.as_uint32());
DCHECK(!probe.IsTheHole(isolate));
Context context = elements->context();
int context_entry = Smi::ToInt(probe);
......@@ -3918,13 +3920,13 @@ class SloppyArgumentsElementsAccessor
static inline void SetImpl(FixedArrayBase store, InternalIndex entry,
Object value) {
SloppyArgumentsElements elements = SloppyArgumentsElements::cast(store);
uint32_t length = elements.parameter_map_length();
uint32_t length = elements.length();
if (entry.as_uint32() < length) {
// Store context mapped entry.
DisallowHeapAllocation no_gc;
Object probe = elements.get_mapped_entry(entry.as_uint32());
Object probe = elements.mapped_entries(entry.as_uint32());
DCHECK(!probe.IsTheHole());
Context context = elements.context();
Context context = Context::cast(elements.context());
int context_entry = Smi::ToInt(probe);
DCHECK(!context.get(context_entry).IsTheHole());
context.set(context_entry, value);
......@@ -3935,7 +3937,7 @@ class SloppyArgumentsElementsAccessor
ArgumentsAccessor::GetRaw(arguments, entry.adjust_down(length));
if (current.IsAliasedArgumentsEntry()) {
AliasedArgumentsEntry alias = AliasedArgumentsEntry::cast(current);
Context context = elements.context();
Context context = Context::cast(elements.context());
int context_entry = alias.aliased_context_slot();
DCHECK(!context.get(context_entry).IsTheHole());
context.set(context_entry, value);
......@@ -3955,7 +3957,7 @@ class SloppyArgumentsElementsAccessor
static uint32_t GetCapacityImpl(JSObject holder, FixedArrayBase store) {
SloppyArgumentsElements elements = SloppyArgumentsElements::cast(store);
FixedArray arguments = elements.arguments();
return elements.parameter_map_length() +
return elements.length() +
ArgumentsAccessor::GetCapacityImpl(holder, arguments);
}
......@@ -3967,7 +3969,7 @@ class SloppyArgumentsElementsAccessor
size_t max_entries =
ArgumentsAccessor::GetMaxNumberOfEntries(holder, arguments);
DCHECK_LE(max_entries, std::numeric_limits<uint32_t>::max());
return elements.parameter_map_length() + static_cast<uint32_t>(max_entries);
return elements.length() + static_cast<uint32_t>(max_entries);
}
static uint32_t NumberOfElementsImpl(JSObject receiver,
......@@ -3977,7 +3979,7 @@ class SloppyArgumentsElementsAccessor
SloppyArgumentsElements::cast(backing_store);
FixedArrayBase arguments = elements.arguments();
uint32_t nof_elements = 0;
uint32_t length = elements.parameter_map_length();
uint32_t length = elements.length();
for (uint32_t index = 0; index < length; index++) {
if (HasParameterMapArg(isolate, elements, index)) nof_elements++;
}
......@@ -4004,7 +4006,7 @@ class SloppyArgumentsElementsAccessor
InternalIndex entry) {
SloppyArgumentsElements elements =
SloppyArgumentsElements::cast(parameters);
uint32_t length = elements.parameter_map_length();
uint32_t length = elements.length();
if (entry.raw_value() < length) {
return HasParameterMapArg(isolate, elements, entry.raw_value());
}
......@@ -4035,13 +4037,13 @@ class SloppyArgumentsElementsAccessor
if (entry.is_not_found()) return entry;
// Arguments entries could overlap with the dictionary entries, hence offset
// them by the number of context mapped entries.
return entry.adjust_up(elements.parameter_map_length());
return entry.adjust_up(elements.length());
}
static PropertyDetails GetDetailsImpl(JSObject holder, InternalIndex entry) {
SloppyArgumentsElements elements =
SloppyArgumentsElements::cast(holder.elements());
uint32_t length = elements.parameter_map_length();
uint32_t length = elements.length();
if (entry.as_uint32() < length) {
return PropertyDetails(kData, NONE, PropertyCellType::kNoCell);
}
......@@ -4053,16 +4055,16 @@ class SloppyArgumentsElementsAccessor
static bool HasParameterMapArg(Isolate* isolate,
SloppyArgumentsElements elements,
size_t index) {
uint32_t length = elements.parameter_map_length();
uint32_t length = elements.length();
if (index >= length) return false;
return !elements.get_mapped_entry(static_cast<uint32_t>(index))
return !elements.mapped_entries(static_cast<uint32_t>(index))
.IsTheHole(isolate);
}
static void DeleteImpl(Handle<JSObject> obj, InternalIndex entry) {
Handle<SloppyArgumentsElements> elements(
SloppyArgumentsElements::cast(obj->elements()), obj->GetIsolate());
uint32_t length = elements->parameter_map_length();
uint32_t length = elements->length();
InternalIndex delete_or_entry = entry;
if (entry.as_uint32() < length) {
delete_or_entry = InternalIndex::NotFound();
......@@ -4071,7 +4073,7 @@ class SloppyArgumentsElementsAccessor
// SloppyDeleteImpl allocates a new dictionary elements store. For making
// heap verification happy we postpone clearing out the mapped entry.
if (entry.as_uint32() < length) {
elements->set_mapped_entry(entry.as_uint32(),
elements->set_mapped_entries(entry.as_uint32(),
obj->GetReadOnlyRoots().the_hole_value());
}
}
......@@ -4107,10 +4109,10 @@ class SloppyArgumentsElementsAccessor
uint32_t insertion_index = 0) {
Handle<SloppyArgumentsElements> elements =
Handle<SloppyArgumentsElements>::cast(backing_store);
uint32_t length = elements->parameter_map_length();
uint32_t length = elements->length();
for (uint32_t i = 0; i < length; ++i) {
if (elements->get_mapped_entry(i).IsTheHole(isolate)) continue;
if (elements->mapped_entries(i).IsTheHole(isolate)) continue;
if (convert == GetKeysConversion::kConvertToString) {
Handle<String> index_string = isolate->factory()->Uint32ToString(i);
list->set(insertion_index, *index_string);
......@@ -4238,7 +4240,7 @@ class SlowSloppyArgumentsElementsAccessor
Isolate* isolate = obj->GetIsolate();
Handle<NumberDictionary> dict(NumberDictionary::cast(elements->arguments()),
isolate);
uint32_t length = elements->parameter_map_length();
uint32_t length = elements->length();
dict =
NumberDictionary::DeleteEntry(isolate, dict, entry.adjust_down(length));
elements->set_arguments(*dict);
......@@ -4271,9 +4273,9 @@ class SlowSloppyArgumentsElementsAccessor
Isolate* isolate = object->GetIsolate();
Handle<SloppyArgumentsElements> elements =
Handle<SloppyArgumentsElements>::cast(store);
uint32_t length = elements->parameter_map_length();
uint32_t length = elements->length();
if (entry.as_uint32() < length) {
Object probe = elements->get_mapped_entry(entry.as_uint32());
Object probe = elements->mapped_entries(entry.as_uint32());
DCHECK(!probe.IsTheHole(isolate));
Context context = elements->context();
int context_entry = Smi::ToInt(probe);
......@@ -4281,7 +4283,7 @@ class SlowSloppyArgumentsElementsAccessor
context.set(context_entry, *value);
// Redefining attributes of an aliased element destroys fast aliasing.
elements->set_mapped_entry(entry.as_uint32(),
elements->set_mapped_entries(entry.as_uint32(),
ReadOnlyRoots(isolate).the_hole_value());
// For elements that are still writable we re-establish slow aliasing.
if ((attributes & READ_ONLY) == 0) {
......@@ -4339,7 +4341,7 @@ class FastSloppyArgumentsElementsAccessor
// kMaxUInt32 indicates that a context mapped element got deleted. In this
// case we only normalize the elements (aka. migrate to SLOW_SLOPPY).
if (entry->is_not_found()) return dictionary;
uint32_t length = elements->parameter_map_length();
uint32_t length = elements->length();
if (entry->as_uint32() >= length) {
*entry =
dictionary
......
......@@ -5,8 +5,6 @@
#ifndef V8_OBJECTS_JS_OBJECTS_INL_H_
#define V8_OBJECTS_JS_OBJECTS_INL_H_
#include "src/objects/js-objects.h"
#include "src/diagnostics/code-tracer.h"
#include "src/heap/heap-write-barrier.h"
#include "src/objects/elements.h"
......@@ -16,6 +14,7 @@
#include "src/objects/field-index-inl.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/heap-number-inl.h"
#include "src/objects/js-objects.h"
#include "src/objects/keys.h"
#include "src/objects/lookup-inl.h"
#include "src/objects/property-array-inl.h"
......@@ -775,9 +774,8 @@ DEF_GETTER(JSObject, GetElementsKind, ElementsKind) {
DCHECK(kind > DICTIONARY_ELEMENTS ||
IsAnyNonextensibleElementsKind(kind));
}
DCHECK(
!IsSloppyArgumentsElementsKind(kind) ||
(elements(isolate).IsFixedArray() && elements(isolate).length() >= 2));
DCHECK(!IsSloppyArgumentsElementsKind(kind) ||
elements(isolate).IsSloppyArgumentsElements());
}
#endif
return kind;
......
......@@ -72,6 +72,8 @@
#include "src/strings/string-stream.h"
#include "src/utils/ostreams.h"
#include "src/wasm/wasm-objects.h"
#include "torque-generated/exported-class-definitions-tq-inl.h"
#include "torque-generated/exported-class-definitions-tq.h"
namespace v8 {
namespace internal {
......
......@@ -14,6 +14,8 @@
#include "src/objects/hash-table-inl.h"
#include "src/objects/heap-number-inl.h"
#include "src/objects/struct-inl.h"
#include "torque-generated/exported-class-definitions-tq-inl.h"
#include "torque-generated/exported-class-definitions-tq.h"
namespace v8 {
namespace internal {
......@@ -763,13 +765,14 @@ void LookupIterator::TransitionToAccessorPair(Handle<Object> pair,
receiver->RequireSlowElements(*dictionary);
if (receiver->HasSlowArgumentsElements(isolate_)) {
FixedArray parameter_map = FixedArray::cast(receiver->elements(isolate_));
uint32_t length = parameter_map.length() - 2;
SloppyArgumentsElements parameter_map =
SloppyArgumentsElements::cast(receiver->elements(isolate_));
uint32_t length = parameter_map.length();
if (number_.is_found() && number_.as_uint32() < length) {
parameter_map.set(number_.as_int() + 2,
ReadOnlyRoots(isolate_).the_hole_value());
parameter_map.set_mapped_entries(
number_.as_int(), ReadOnlyRoots(isolate_).the_hole_value());
}
FixedArray::cast(receiver->elements(isolate_)).set(1, *dictionary);
parameter_map.set_arguments(*dictionary);
} else {
receiver->set_elements(*dictionary);
}
......
......@@ -227,8 +227,6 @@ FixedArrayBase Map::GetInitialElements() const {
if (has_fast_elements() || has_fast_string_wrapper_elements() ||
has_any_nonextensible_elements()) {
result = GetReadOnlyRoots().empty_fixed_array();
} else if (has_fast_sloppy_arguments_elements()) {
result = GetReadOnlyRoots().empty_sloppy_arguments_elements();
} else if (has_typed_array_elements()) {
result = GetReadOnlyRoots().empty_byte_array();
} else if (has_dictionary_elements()) {
......
......@@ -202,7 +202,6 @@ class ZoneForwardList;
V(SharedFunctionInfo) \
V(SimpleNumberDictionary) \
V(SlicedString) \
V(SloppyArgumentsElements) \
V(SmallOrderedHashMap) \
V(SmallOrderedHashSet) \
V(SmallOrderedNameDictionary) \
......
......@@ -67,10 +67,6 @@ int PropertyDetails::field_width_in_words() const {
return representation().IsDouble() ? kDoubleSize / kTaggedSize : 1;
}
DEF_GETTER(HeapObject, IsSloppyArgumentsElements, bool) {
return IsFixedArrayExact(isolate);
}
DEF_GETTER(HeapObject, IsClassBoilerplate, bool) {
return IsFixedArrayExact(isolate);
}
......
......@@ -108,7 +108,6 @@ class Symbol;
V(Map, next_call_side_effect_free_call_handler_info_map, \
NextCallSideEffectFreeCallHandlerInfoMap) \
V(Map, simple_number_dictionary_map, SimpleNumberDictionaryMap) \
V(Map, sloppy_arguments_elements_map, SloppyArgumentsElementsMap) \
V(Map, small_ordered_hash_map_map, SmallOrderedHashMapMap) \
V(Map, small_ordered_hash_set_map, SmallOrderedHashSetMap) \
V(Map, small_ordered_name_dictionary_map, SmallOrderedNameDictionaryMap) \
......@@ -167,7 +166,6 @@ class Symbol;
EmptyArrayBoilerplateDescription) \
V(ClosureFeedbackCellArray, empty_closure_feedback_cell_array, \
EmptyClosureFeedbackCellArray) \
V(FixedArray, empty_sloppy_arguments_elements, EmptySloppyArgumentsElements) \
V(NumberDictionary, empty_slow_element_dictionary, \
EmptySlowElementDictionary) \
V(FixedArray, empty_ordered_hash_map, EmptyOrderedHashMap) \
......
......@@ -18,6 +18,8 @@
#include "src/objects/module-inl.h"
#include "src/objects/smi.h"
#include "src/runtime/runtime-utils.h"
#include "torque-generated/exported-class-definitions-tq-inl.h"
#include "torque-generated/exported-class-definitions-tq.h"
namespace v8 {
namespace internal {
......@@ -408,20 +410,19 @@ Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee,
if (argument_count > 0) {
if (parameter_count > 0) {
int mapped_count = Min(argument_count, parameter_count);
Handle<FixedArray> parameter_map = isolate->factory()->NewFixedArray(
mapped_count + 2, AllocationType::kYoung);
parameter_map->set_map(
ReadOnlyRoots(isolate).sloppy_arguments_elements_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
// parameter map.
Handle<Context> context(isolate->context(), isolate);
Handle<FixedArray> arguments = isolate->factory()->NewFixedArray(
argument_count, AllocationType::kYoung);
parameter_map->set(0, *context);
parameter_map->set(1, *arguments);
Handle<SloppyArgumentsElements> parameter_map =
isolate->factory()->NewSloppyArgumentsElements(
mapped_count, context, arguments, AllocationType::kYoung);
result->set_map(isolate->native_context()->fast_aliased_arguments_map());
result->set_elements(*parameter_map);
// Loop over the actual parameters backwards.
int index = argument_count - 1;
......@@ -438,7 +439,8 @@ Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee,
// arguments object.
for (int i = 0; i < mapped_count; i++) {
arguments->set(i, parameters[i]);
parameter_map->set_the_hole(i + 2);
parameter_map->set_mapped_entries(
i, *isolate->factory()->the_hole_value());
}
// Walk all context slots to find context allocated parameters. Mark each
......@@ -449,7 +451,7 @@ Handle<JSObject> NewSloppyArguments(Isolate* isolate, Handle<JSFunction> callee,
if (parameter >= mapped_count) continue;
arguments->set_the_hole(parameter);
Smi slot = Smi::FromInt(scope_info->ContextHeaderLength() + i);
parameter_map->set(parameter + 2, slot);
parameter_map->set_mapped_entries(parameter, slot);
}
} else {
// If there is no aliasing, the arguments object elements are not
......
This diff is collapsed.
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