Commit c7d01c42 authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

[proxies] Use write barriers for Proxy [[Construct]] arguments

The number of arguments passed on the stack might exceed the regular
object size limits. Hence we need to emit write barriers when copying
the arguments from the stack into the allocated array.

Bug: chromium:813450
Change-Id: I829c5c32b1a7b5f4ddb01cc6ea92f85ab47126aa
Reviewed-on: https://chromium-review.googlesource.com/939174Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51603}
parent 7c51c944
......@@ -73,22 +73,57 @@ Node* ProxiesCodeStubAssembler::AllocateProxy(Node* target, Node* handler,
Node* ProxiesCodeStubAssembler::AllocateJSArrayForCodeStubArguments(
Node* context, CodeStubArguments& args, Node* argc, ParameterMode mode) {
Comment("AllocateJSArrayForCodeStubArguments");
Label if_empty_array(this), allocate_js_array(this);
// Do not use AllocateJSArray since {elements} might end up in LOS.
VARIABLE(elements, MachineRepresentation::kTagged);
TNode<Smi> length = ParameterToTagged(argc, mode);
GotoIf(SmiEqual(length, SmiConstant(0)), &if_empty_array);
{
Label if_large_object(this, Label::kDeferred);
Node* allocated_elements = AllocateFixedArray(PACKED_ELEMENTS, argc, mode,
kAllowLargeObjectAllocation);
elements.Bind(allocated_elements);
VARIABLE(index, MachineType::PointerRepresentation(),
IntPtrConstant(FixedArrayBase::kHeaderSize - kHeapObjectTag));
VariableList list({&index}, zone());
GotoIf(SmiGreaterThan(length, SmiConstant(FixedArray::kMaxRegularLength)),
&if_large_object);
args.ForEach(list, [=, &index](Node* arg) {
StoreNoWriteBarrier(MachineRepresentation::kTagged, allocated_elements,
index.value(), arg);
Increment(&index, kPointerSize);
});
Goto(&allocate_js_array);
BIND(&if_large_object);
{
args.ForEach(list, [=, &index](Node* arg) {
Store(allocated_elements, index.value(), arg);
Increment(&index, kPointerSize);
});
Goto(&allocate_js_array);
}
}
BIND(&if_empty_array);
{
elements.Bind(EmptyFixedArrayConstant());
Goto(&allocate_js_array);
}
BIND(&allocate_js_array);
// Allocate the result JSArray.
Node* native_context = LoadNativeContext(context);
Node* array_map = LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context);
Node* argc_smi = ParameterToTagged(argc, mode);
Node* array = AllocateJSArray(PACKED_ELEMENTS, array_map, argc, argc_smi,
nullptr, mode);
Node* elements = LoadElements(array);
VARIABLE(index, MachineType::PointerRepresentation(),
IntPtrConstant(FixedArrayBase::kHeaderSize - kHeapObjectTag));
VariableList list({&index}, zone());
args.ForEach(list, [=, &index](Node* arg) {
StoreNoWriteBarrier(MachineRepresentation::kTagged, elements, index.value(),
arg);
Increment(&index, kPointerSize);
});
Node* array = AllocateUninitializedJSArrayWithoutElements(array_map, length);
StoreObjectFieldNoWriteBarrier(array, JSObject::kElementsOffset,
elements.value());
return array;
}
......
......@@ -3127,6 +3127,7 @@ Node* CodeStubAssembler::AllocateFixedArray(ElementsKind kind,
ParameterMode mode,
AllocationFlags flags,
Node* fixed_array_map) {
Comment("AllocateFixedArray");
CSA_SLOW_ASSERT(this, MatchesParameterMode(capacity_node, mode));
CSA_ASSERT(this, IntPtrOrSmiGreaterThan(capacity_node,
IntPtrOrSmiConstant(0, mode), mode));
......
......@@ -831,9 +831,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
int start_offset = JSObject::kHeaderSize);
// Allocate a JSArray without elements and initialize the header fields.
Node* AllocateUninitializedJSArrayWithoutElements(Node* array_map,
Node* length,
Node* allocation_site);
Node* AllocateUninitializedJSArrayWithoutElements(
Node* array_map, Node* length, Node* allocation_site = nullptr);
// Allocate and return a JSArray with initialized header fields and its
// uninitialized elements.
// The ParameterMode argument is only used for the capacity parameter.
......
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax
var constructorArgs = new Array(0x10100);
var constructor = function() {};
var target = new Proxy(constructor, {
construct: function() {
}
});
var proxy = new Proxy(target, {
construct: function(newTarget, args) {
return Reflect.construct(constructor, []);
}
});
var instance = new proxy();
var instance2 = Reflect.construct(proxy, constructorArgs);
%HeapObjectVerify(target);
%HeapObjectVerify(proxy);
%HeapObjectVerify(instance);
%HeapObjectVerify(instance2);
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