Commit eb2906ae authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[compiler] Don't try to inline allocate large arguments arrays

... otherwise we'd abort at runtime.

Bug: chromium:1178076
Change-Id: Ic7b4a3b27379ec0d42419e2695ab487904eabd72
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2695395Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72744}
parent 053d1e0d
...@@ -27,11 +27,21 @@ void AllocationBuilder::AllocateContext(int variadic_part_length, MapRef map) { ...@@ -27,11 +27,21 @@ void AllocationBuilder::AllocateContext(int variadic_part_length, MapRef map) {
jsgraph()->Constant(variadic_part_length)); jsgraph()->Constant(variadic_part_length));
} }
// static
bool AllocationBuilder::CanAllocateArray(int length, MapRef map,
AllocationType allocation) {
DCHECK(map.instance_type() == FIXED_ARRAY_TYPE ||
map.instance_type() == FIXED_DOUBLE_ARRAY_TYPE);
int const size = (map.instance_type() == FIXED_ARRAY_TYPE)
? FixedArray::SizeFor(length)
: FixedDoubleArray::SizeFor(length);
return size <= Heap::MaxRegularHeapObjectSize(allocation);
}
// Compound allocation of a FixedArray. // Compound allocation of a FixedArray.
void AllocationBuilder::AllocateArray(int length, MapRef map, void AllocationBuilder::AllocateArray(int length, MapRef map,
AllocationType allocation) { AllocationType allocation) {
DCHECK(map.instance_type() == FIXED_ARRAY_TYPE || DCHECK(CanAllocateArray(length, map, allocation));
map.instance_type() == FIXED_DOUBLE_ARRAY_TYPE);
int size = (map.instance_type() == FIXED_ARRAY_TYPE) int size = (map.instance_type() == FIXED_ARRAY_TYPE)
? FixedArray::SizeFor(length) ? FixedArray::SizeFor(length)
: FixedDoubleArray::SizeFor(length); : FixedDoubleArray::SizeFor(length);
...@@ -40,8 +50,16 @@ void AllocationBuilder::AllocateArray(int length, MapRef map, ...@@ -40,8 +50,16 @@ void AllocationBuilder::AllocateArray(int length, MapRef map,
Store(AccessBuilder::ForFixedArrayLength(), jsgraph()->Constant(length)); Store(AccessBuilder::ForFixedArrayLength(), jsgraph()->Constant(length));
} }
// static
bool AllocationBuilder::CanAllocateSloppyArgumentElements(
int length, MapRef map, AllocationType allocation) {
int const size = SloppyArgumentsElements::SizeFor(length);
return size <= Heap::MaxRegularHeapObjectSize(allocation);
}
void AllocationBuilder::AllocateSloppyArgumentElements( void AllocationBuilder::AllocateSloppyArgumentElements(
int length, MapRef map, AllocationType allocation) { int length, MapRef map, AllocationType allocation) {
DCHECK(CanAllocateSloppyArgumentElements(length, map, allocation));
int size = SloppyArgumentsElements::SizeFor(length); int size = SloppyArgumentsElements::SizeFor(length);
Allocate(size, allocation, Type::OtherInternal()); Allocate(size, allocation, Type::OtherInternal());
Store(AccessBuilder::ForMap(), map); Store(AccessBuilder::ForMap(), map);
......
...@@ -52,10 +52,16 @@ class AllocationBuilder final { ...@@ -52,10 +52,16 @@ class AllocationBuilder final {
inline void AllocateContext(int variadic_part_length, MapRef map); inline void AllocateContext(int variadic_part_length, MapRef map);
// Compound allocation of a FixedArray. // Compound allocation of a FixedArray.
inline static bool CanAllocateArray(
int length, MapRef map,
AllocationType allocation = AllocationType::kYoung);
inline void AllocateArray(int length, MapRef map, inline void AllocateArray(int length, MapRef map,
AllocationType allocation = AllocationType::kYoung); AllocationType allocation = AllocationType::kYoung);
// Compound allocation of a SloppyArgumentsElements // Compound allocation of a SloppyArgumentsElements
static inline bool CanAllocateSloppyArgumentElements(
int length, MapRef map,
AllocationType allocation = AllocationType::kYoung);
inline void AllocateSloppyArgumentElements( inline void AllocateSloppyArgumentElements(
int length, MapRef map, int length, MapRef map,
AllocationType allocation = AllocationType::kYoung); AllocationType allocation = AllocationType::kYoung);
......
...@@ -168,9 +168,11 @@ Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) { ...@@ -168,9 +168,11 @@ Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) {
graph()->NewNode(simplified()->ArgumentsLength()); graph()->NewNode(simplified()->ArgumentsLength());
// Allocate the elements backing store. // Allocate the elements backing store.
bool has_aliased_arguments = false; bool has_aliased_arguments = false;
Node* const elements = effect = Node* const elements = effect = TryAllocateAliasedArguments(
AllocateAliasedArguments(effect, control, context, arguments_length, effect, control, context, arguments_length, shared,
shared, &has_aliased_arguments); &has_aliased_arguments);
if (elements == nullptr) return NoChange();
// Load the arguments object map. // Load the arguments object map.
Node* const arguments_map = jsgraph()->Constant( Node* const arguments_map = jsgraph()->Constant(
has_aliased_arguments has_aliased_arguments
...@@ -269,15 +271,11 @@ Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) { ...@@ -269,15 +271,11 @@ Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) {
} }
FrameStateInfo args_state_info = args_state.frame_state_info(); FrameStateInfo args_state_info = args_state.frame_state_info();
int length = args_state_info.parameter_count() - 1; // Minus receiver. int length = args_state_info.parameter_count() - 1; // Minus receiver.
// Check that the array allocated for arguments is not "large".
{
const int alloc_size = FixedArray::SizeFor(length);
if (alloc_size > kMaxRegularHeapObjectSize) return NoChange();
}
// Prepare element backing store to be used by arguments object. // Prepare element backing store to be used by arguments object.
bool has_aliased_arguments = false; bool has_aliased_arguments = false;
Node* const elements = AllocateAliasedArguments( Node* const elements = TryAllocateAliasedArguments(
effect, control, args_state, context, shared, &has_aliased_arguments); effect, control, args_state, context, shared, &has_aliased_arguments);
if (elements == nullptr) return NoChange();
effect = elements->op()->EffectOutputCount() > 0 ? elements : effect; effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
// Load the arguments object map. // Load the arguments object map.
Node* const arguments_map = jsgraph()->Constant( Node* const arguments_map = jsgraph()->Constant(
...@@ -313,13 +311,9 @@ Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) { ...@@ -313,13 +311,9 @@ Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) {
} }
FrameStateInfo args_state_info = args_state.frame_state_info(); FrameStateInfo args_state_info = args_state.frame_state_info();
int length = args_state_info.parameter_count() - 1; // Minus receiver. int length = args_state_info.parameter_count() - 1; // Minus receiver.
// Check that the array allocated for arguments is not "large".
{
const int alloc_size = FixedArray::SizeFor(length);
if (alloc_size > kMaxRegularHeapObjectSize) return NoChange();
}
// Prepare element backing store to be used by arguments object. // Prepare element backing store to be used by arguments object.
Node* const elements = AllocateArguments(effect, control, args_state); Node* const elements = TryAllocateArguments(effect, control, args_state);
if (elements == nullptr) return NoChange();
effect = elements->op()->EffectOutputCount() > 0 ? elements : effect; effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
// Load the arguments object map. // Load the arguments object map.
Node* const arguments_map = Node* const arguments_map =
...@@ -355,7 +349,8 @@ Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) { ...@@ -355,7 +349,8 @@ Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) {
FrameStateInfo args_state_info = args_state.frame_state_info(); FrameStateInfo args_state_info = args_state.frame_state_info();
// Prepare element backing store to be used by the rest array. // Prepare element backing store to be used by the rest array.
Node* const elements = Node* const elements =
AllocateRestArguments(effect, control, args_state, start_index); TryAllocateRestArguments(effect, control, args_state, start_index);
if (elements == nullptr) return NoChange();
effect = elements->op()->EffectOutputCount() > 0 ? elements : effect; effect = elements->op()->EffectOutputCount() > 0 ? elements : effect;
// Load the JSArray object map. // Load the JSArray object map.
Node* const jsarray_map = Node* const jsarray_map =
...@@ -407,11 +402,15 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) { ...@@ -407,11 +402,15 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
SharedFunctionInfoRef shared = js_function.shared(); SharedFunctionInfoRef shared = js_function.shared();
DCHECK(shared.HasBytecodeArray()); DCHECK(shared.HasBytecodeArray());
int parameter_count_no_receiver = shared.internal_formal_parameter_count(); int parameter_count_no_receiver = shared.internal_formal_parameter_count();
int size = parameter_count_no_receiver + int length = parameter_count_no_receiver +
shared.GetBytecodeArray().register_count(); shared.GetBytecodeArray().register_count();
MapRef fixed_array_map(broker(), factory()->fixed_array_map());
AllocationBuilder ab(jsgraph(), effect, control); AllocationBuilder ab(jsgraph(), effect, control);
ab.AllocateArray(size, MapRef(broker(), factory()->fixed_array_map())); if (!ab.CanAllocateArray(length, fixed_array_map)) {
for (int i = 0; i < size; ++i) { return NoChange();
}
ab.AllocateArray(length, fixed_array_map);
for (int i = 0; i < length; ++i) {
ab.Store(AccessBuilder::ForFixedArraySlot(i), ab.Store(AccessBuilder::ForFixedArraySlot(i),
jsgraph()->UndefinedConstant()); jsgraph()->UndefinedConstant());
} }
...@@ -776,9 +775,12 @@ Reduction JSCreateLowering::ReduceJSCreateAsyncFunctionObject(Node* node) { ...@@ -776,9 +775,12 @@ Reduction JSCreateLowering::ReduceJSCreateAsyncFunctionObject(Node* node) {
Node* control = NodeProperties::GetControlInput(node); Node* control = NodeProperties::GetControlInput(node);
// Create the register file. // Create the register file.
MapRef fixed_array_map(broker(), factory()->fixed_array_map());
AllocationBuilder ab(jsgraph(), effect, control); AllocationBuilder ab(jsgraph(), effect, control);
ab.AllocateArray(register_count, if (!ab.CanAllocateArray(register_count, fixed_array_map)) {
MapRef(broker(), factory()->fixed_array_map())); return NoChange();
}
ab.AllocateArray(register_count, fixed_array_map);
for (int i = 0; i < register_count; ++i) { for (int i = 0; i < register_count; ++i) {
ab.Store(AccessBuilder::ForFixedArraySlot(i), ab.Store(AccessBuilder::ForFixedArraySlot(i),
jsgraph()->UndefinedConstant()); jsgraph()->UndefinedConstant());
...@@ -888,13 +890,17 @@ Reduction JSCreateLowering::ReduceJSCreateBoundFunction(Node* node) { ...@@ -888,13 +890,17 @@ Reduction JSCreateLowering::ReduceJSCreateBoundFunction(Node* node) {
// Create the [[BoundArguments]] for the result. // Create the [[BoundArguments]] for the result.
Node* bound_arguments = jsgraph()->EmptyFixedArrayConstant(); Node* bound_arguments = jsgraph()->EmptyFixedArrayConstant();
if (arity > 0) { if (arity > 0) {
AllocationBuilder a(jsgraph(), effect, control); MapRef fixed_array_map(broker(), factory()->fixed_array_map());
a.AllocateArray(arity, MapRef(broker(), factory()->fixed_array_map())); AllocationBuilder ab(jsgraph(), effect, control);
if (!ab.CanAllocateArray(arity, fixed_array_map)) {
return NoChange();
}
ab.AllocateArray(arity, fixed_array_map);
for (int i = 0; i < arity; ++i) { for (int i = 0; i < arity; ++i) {
a.Store(AccessBuilder::ForFixedArraySlot(i), ab.Store(AccessBuilder::ForFixedArraySlot(i),
NodeProperties::GetValueInput(node, 2 + i)); NodeProperties::GetValueInput(node, 2 + i));
} }
bound_arguments = effect = a.Finish(); bound_arguments = effect = ab.Finish();
} }
// Create the JSBoundFunction result. // Create the JSBoundFunction result.
...@@ -1412,8 +1418,8 @@ Reduction JSCreateLowering::ReduceJSCreateObject(Node* node) { ...@@ -1412,8 +1418,8 @@ Reduction JSCreateLowering::ReduceJSCreateObject(Node* node) {
// Helper that allocates a FixedArray holding argument values recorded in the // Helper that allocates a FixedArray holding argument values recorded in the
// given {frame_state}. Serves as backing store for JSCreateArguments nodes. // given {frame_state}. Serves as backing store for JSCreateArguments nodes.
Node* JSCreateLowering::AllocateArguments(Node* effect, Node* control, Node* JSCreateLowering::TryAllocateArguments(Node* effect, Node* control,
FrameState frame_state) { FrameState frame_state) {
FrameStateInfo state_info = frame_state.frame_state_info(); FrameStateInfo state_info = frame_state.frame_state_info();
int argument_count = state_info.parameter_count() - 1; // Minus receiver. int argument_count = state_info.parameter_count() - 1; // Minus receiver.
if (argument_count == 0) return jsgraph()->EmptyFixedArrayConstant(); if (argument_count == 0) return jsgraph()->EmptyFixedArrayConstant();
...@@ -1424,22 +1430,25 @@ Node* JSCreateLowering::AllocateArguments(Node* effect, Node* control, ...@@ -1424,22 +1430,25 @@ Node* JSCreateLowering::AllocateArguments(Node* effect, Node* control,
auto parameters_it = parameters_access.begin_without_receiver(); auto parameters_it = parameters_access.begin_without_receiver();
// Actually allocate the backing store. // Actually allocate the backing store.
AllocationBuilder a(jsgraph(), effect, control); MapRef fixed_array_map(broker(), factory()->fixed_array_map());
a.AllocateArray(argument_count, AllocationBuilder ab(jsgraph(), effect, control);
MapRef(broker(), factory()->fixed_array_map())); if (!ab.CanAllocateArray(argument_count, fixed_array_map)) {
return nullptr;
}
ab.AllocateArray(argument_count, fixed_array_map);
for (int i = 0; i < argument_count; ++i, ++parameters_it) { for (int i = 0; i < argument_count; ++i, ++parameters_it) {
DCHECK_NOT_NULL(parameters_it.node()); DCHECK_NOT_NULL(parameters_it.node());
a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i), ab.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
parameters_it.node()); parameters_it.node());
} }
return a.Finish(); return ab.Finish();
} }
// Helper that allocates a FixedArray holding argument values recorded in the // Helper that allocates a FixedArray holding argument values recorded in the
// given {frame_state}. Serves as backing store for JSCreateArguments nodes. // given {frame_state}. Serves as backing store for JSCreateArguments nodes.
Node* JSCreateLowering::AllocateRestArguments(Node* effect, Node* control, Node* JSCreateLowering::TryAllocateRestArguments(Node* effect, Node* control,
FrameState frame_state, FrameState frame_state,
int start_index) { int start_index) {
FrameStateInfo state_info = frame_state.frame_state_info(); FrameStateInfo state_info = frame_state.frame_state_info();
int argument_count = state_info.parameter_count() - 1; // Minus receiver. int argument_count = state_info.parameter_count() - 1; // Minus receiver.
int num_elements = std::max(0, argument_count - start_index); int num_elements = std::max(0, argument_count - start_index);
...@@ -1452,20 +1461,24 @@ Node* JSCreateLowering::AllocateRestArguments(Node* effect, Node* control, ...@@ -1452,20 +1461,24 @@ Node* JSCreateLowering::AllocateRestArguments(Node* effect, Node* control,
parameters_access.begin_without_receiver_and_skip(start_index); parameters_access.begin_without_receiver_and_skip(start_index);
// Actually allocate the backing store. // Actually allocate the backing store.
AllocationBuilder a(jsgraph(), effect, control); MapRef fixed_array_map(broker(), factory()->fixed_array_map());
a.AllocateArray(num_elements, MapRef(broker(), factory()->fixed_array_map())); AllocationBuilder ab(jsgraph(), effect, control);
if (!ab.CanAllocateArray(num_elements, fixed_array_map)) {
return nullptr;
}
ab.AllocateArray(num_elements, fixed_array_map);
for (int i = 0; i < num_elements; ++i, ++parameters_it) { for (int i = 0; i < num_elements; ++i, ++parameters_it) {
DCHECK_NOT_NULL(parameters_it.node()); DCHECK_NOT_NULL(parameters_it.node());
a.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i), ab.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
parameters_it.node()); parameters_it.node());
} }
return a.Finish(); return ab.Finish();
} }
// Helper that allocates a FixedArray serving as a parameter map for values // Helper that allocates a FixedArray serving as a parameter map for values
// recorded in the given {frame_state}. Some elements map to slots within the // recorded in the given {frame_state}. Some elements map to slots within the
// given {context}. Serves as backing store for JSCreateArguments nodes. // given {context}. Serves as backing store for JSCreateArguments nodes.
Node* JSCreateLowering::AllocateAliasedArguments( Node* JSCreateLowering::TryAllocateAliasedArguments(
Node* effect, Node* control, FrameState frame_state, Node* context, Node* effect, Node* control, FrameState frame_state, Node* context,
const SharedFunctionInfoRef& shared, bool* has_aliased_arguments) { const SharedFunctionInfoRef& shared, bool* has_aliased_arguments) {
FrameStateInfo state_info = frame_state.frame_state_info(); FrameStateInfo state_info = frame_state.frame_state_info();
...@@ -1476,13 +1489,25 @@ Node* JSCreateLowering::AllocateAliasedArguments( ...@@ -1476,13 +1489,25 @@ Node* JSCreateLowering::AllocateAliasedArguments(
// any way, we can just return an unmapped backing store instead. // any way, we can just return an unmapped backing store instead.
int parameter_count = shared.internal_formal_parameter_count(); int parameter_count = shared.internal_formal_parameter_count();
if (parameter_count == 0) { if (parameter_count == 0) {
return AllocateArguments(effect, control, frame_state); return TryAllocateArguments(effect, control, frame_state);
} }
// Calculate number of argument values being aliased/mapped. // Calculate number of argument values being aliased/mapped.
int mapped_count = std::min(argument_count, parameter_count); int mapped_count = std::min(argument_count, parameter_count);
*has_aliased_arguments = true; *has_aliased_arguments = true;
MapRef sloppy_arguments_elements_map(
broker(), factory()->sloppy_arguments_elements_map());
if (AllocationBuilder::CanAllocateSloppyArgumentElements(
mapped_count, sloppy_arguments_elements_map)) {
return nullptr;
}
MapRef fixed_array_map(broker(), factory()->fixed_array_map());
if (!AllocationBuilder::CanAllocateArray(argument_count, fixed_array_map)) {
return nullptr;
}
// Prepare an iterator over argument values recorded in the frame state. // Prepare an iterator over argument values recorded in the frame state.
Node* const parameters = frame_state.parameters(); Node* const parameters = frame_state.parameters();
StateValuesAccess parameters_access(parameters); StateValuesAccess parameters_access(parameters);
...@@ -1492,25 +1517,23 @@ Node* JSCreateLowering::AllocateAliasedArguments( ...@@ -1492,25 +1517,23 @@ Node* JSCreateLowering::AllocateAliasedArguments(
// The unmapped argument values recorded in the frame state are stored yet // The unmapped argument values recorded in the frame state are stored yet
// another indirection away and then linked into the parameter map below, // another indirection away and then linked into the parameter map below,
// whereas mapped argument values are replaced with a hole instead. // whereas mapped argument values are replaced with a hole instead.
AllocationBuilder aa(jsgraph(), effect, control); AllocationBuilder ab(jsgraph(), effect, control);
aa.AllocateArray(argument_count, ab.AllocateArray(argument_count,
MapRef(broker(), factory()->fixed_array_map())); MapRef(broker(), factory()->fixed_array_map()));
for (int i = 0; i < mapped_count; ++i) { for (int i = 0; i < mapped_count; ++i) {
aa.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i), ab.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
jsgraph()->TheHoleConstant()); jsgraph()->TheHoleConstant());
} }
for (int i = mapped_count; i < argument_count; ++i, ++parameters_it) { for (int i = mapped_count; i < argument_count; ++i, ++parameters_it) {
DCHECK_NOT_NULL(parameters_it.node()); DCHECK_NOT_NULL(parameters_it.node());
aa.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i), ab.Store(AccessBuilder::ForFixedArrayElement(), jsgraph()->Constant(i),
parameters_it.node()); parameters_it.node());
} }
Node* arguments = aa.Finish(); Node* arguments = ab.Finish();
// Actually allocate the backing store. // Actually allocate the backing store.
AllocationBuilder a(jsgraph(), arguments, control); AllocationBuilder a(jsgraph(), arguments, control);
a.AllocateSloppyArgumentElements( a.AllocateSloppyArgumentElements(mapped_count, sloppy_arguments_elements_map);
mapped_count,
MapRef(broker(), factory()->sloppy_arguments_elements_map()));
a.Store(AccessBuilder::ForSloppyArgumentsElementsContext(), context); a.Store(AccessBuilder::ForSloppyArgumentsElementsContext(), context);
a.Store(AccessBuilder::ForSloppyArgumentsElementsArguments(), arguments); a.Store(AccessBuilder::ForSloppyArgumentsElementsArguments(), arguments);
for (int i = 0; i < mapped_count; ++i) { for (int i = 0; i < mapped_count; ++i) {
...@@ -1525,7 +1548,7 @@ Node* JSCreateLowering::AllocateAliasedArguments( ...@@ -1525,7 +1548,7 @@ Node* JSCreateLowering::AllocateAliasedArguments(
// unknown at compile-time, the true {arguments_length} and {arguments_frame} // unknown at compile-time, the true {arguments_length} and {arguments_frame}
// values can only be determined dynamically at run-time and are provided. // values can only be determined dynamically at run-time and are provided.
// Serves as backing store for JSCreateArguments nodes. // Serves as backing store for JSCreateArguments nodes.
Node* JSCreateLowering::AllocateAliasedArguments( Node* JSCreateLowering::TryAllocateAliasedArguments(
Node* effect, Node* control, Node* context, Node* arguments_length, Node* effect, Node* control, Node* context, Node* arguments_length,
const SharedFunctionInfoRef& shared, bool* has_aliased_arguments) { const SharedFunctionInfoRef& shared, bool* has_aliased_arguments) {
// If there is no aliasing, the arguments object elements are not // If there is no aliasing, the arguments object elements are not
...@@ -1538,11 +1561,18 @@ Node* JSCreateLowering::AllocateAliasedArguments( ...@@ -1538,11 +1561,18 @@ Node* JSCreateLowering::AllocateAliasedArguments(
arguments_length, effect); arguments_length, effect);
} }
int mapped_count = parameter_count;
MapRef sloppy_arguments_elements_map(
broker(), factory()->sloppy_arguments_elements_map());
if (AllocationBuilder::CanAllocateSloppyArgumentElements(
mapped_count, sloppy_arguments_elements_map)) {
return nullptr;
}
// From here on we are going to allocate a mapped (aka. aliased) elements // From here on we are going to allocate a mapped (aka. aliased) elements
// backing store. We do not statically know how many arguments exist, but // backing store. We do not statically know how many arguments exist, but
// dynamically selecting the hole for some of the "mapped" elements allows // dynamically selecting the hole for some of the "mapped" elements allows
// using a static shape for the parameter map. // using a static shape for the parameter map.
int mapped_count = parameter_count;
*has_aliased_arguments = true; *has_aliased_arguments = true;
// The unmapped argument values are stored yet another indirection away and // The unmapped argument values are stored yet another indirection away and
...@@ -1555,9 +1585,7 @@ Node* JSCreateLowering::AllocateAliasedArguments( ...@@ -1555,9 +1585,7 @@ Node* JSCreateLowering::AllocateAliasedArguments(
// Actually allocate the backing store. // Actually allocate the backing store.
AllocationBuilder a(jsgraph(), effect, control); AllocationBuilder a(jsgraph(), effect, control);
a.AllocateSloppyArgumentElements( a.AllocateSloppyArgumentElements(mapped_count, sloppy_arguments_elements_map);
mapped_count,
MapRef(broker(), factory()->sloppy_arguments_elements_map()));
a.Store(AccessBuilder::ForSloppyArgumentsElementsContext(), context); a.Store(AccessBuilder::ForSloppyArgumentsElementsContext(), context);
a.Store(AccessBuilder::ForSloppyArgumentsElementsArguments(), arguments); a.Store(AccessBuilder::ForSloppyArgumentsElementsArguments(), arguments);
for (int i = 0; i < mapped_count; ++i) { for (int i = 0; i < mapped_count; ++i) {
...@@ -1758,16 +1786,18 @@ Node* JSCreateLowering::AllocateFastLiteralElements(Node* effect, Node* control, ...@@ -1758,16 +1786,18 @@ Node* JSCreateLowering::AllocateFastLiteralElements(Node* effect, Node* control,
} }
// Allocate the backing store array and store the elements. // Allocate the backing store array and store the elements.
AllocationBuilder builder(jsgraph(), effect, control); MapRef fixed_array_map(broker(), factory()->fixed_array_map());
builder.AllocateArray(elements_length, elements_map, allocation); AllocationBuilder ab(jsgraph(), effect, control);
CHECK(ab.CanAllocateArray(elements_length, elements_map, allocation));
ab.AllocateArray(elements_length, elements_map, allocation);
ElementAccess const access = ElementAccess const access =
(elements_map.instance_type() == FIXED_DOUBLE_ARRAY_TYPE) (elements_map.instance_type() == FIXED_DOUBLE_ARRAY_TYPE)
? AccessBuilder::ForFixedDoubleArrayElement() ? AccessBuilder::ForFixedDoubleArrayElement()
: AccessBuilder::ForFixedArrayElement(); : AccessBuilder::ForFixedArrayElement();
for (int i = 0; i < elements_length; ++i) { for (int i = 0; i < elements_length; ++i) {
builder.Store(access, jsgraph()->Constant(i), elements_values[i]); ab.Store(access, jsgraph()->Constant(i), elements_values[i]);
} }
return builder.Finish(); return ab.Finish();
} }
Node* JSCreateLowering::AllocateLiteralRegExp( Node* JSCreateLowering::AllocateLiteralRegExp(
......
...@@ -83,17 +83,21 @@ class V8_EXPORT_PRIVATE JSCreateLowering final ...@@ -83,17 +83,21 @@ class V8_EXPORT_PRIVATE JSCreateLowering final
const SlackTrackingPrediction& slack_tracking_prediction); const SlackTrackingPrediction& slack_tracking_prediction);
Reduction ReduceJSCreateObject(Node* node); Reduction ReduceJSCreateObject(Node* node);
Node* AllocateArguments(Node* effect, Node* control, FrameState frame_state); // The following functions all return nullptr iff there are too many arguments
Node* AllocateRestArguments(Node* effect, Node* control, // for inline allocation.
FrameState frame_state, int start_index); Node* TryAllocateArguments(Node* effect, Node* control,
Node* AllocateAliasedArguments(Node* effect, Node* control, FrameState frame_state);
FrameState frame_state, Node* context, Node* TryAllocateRestArguments(Node* effect, Node* control,
const SharedFunctionInfoRef& shared, FrameState frame_state, int start_index);
bool* has_aliased_arguments); Node* TryAllocateAliasedArguments(Node* effect, Node* control,
Node* AllocateAliasedArguments(Node* effect, Node* control, Node* context, FrameState frame_state, Node* context,
Node* arguments_length, const SharedFunctionInfoRef& shared,
const SharedFunctionInfoRef& shared, bool* has_aliased_arguments);
bool* has_aliased_arguments); Node* TryAllocateAliasedArguments(Node* effect, Node* control, Node* context,
Node* arguments_length,
const SharedFunctionInfoRef& shared,
bool* has_aliased_arguments);
Node* AllocateElements(Node* effect, Node* control, Node* AllocateElements(Node* effect, Node* control,
ElementsKind elements_kind, int capacity, ElementsKind elements_kind, int capacity,
AllocationType allocation); AllocationType allocation);
......
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