[torque] Remove constexpr from Arguments object type

In the process turn the Torque's Arguments type into a real struct
and add interoperability with it and CSA's CodeStubArguments.

This change is motivated by the desire to include Arguments
in structs (e.g. iterators), which is not possible for constexpr
fields.

Bug: v8:7793
Change-Id: I840538b84c4c58fee75e0b9cd3bdbb3b96a6b948
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1549162
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60597}
This commit is contained in:
Daniel Clifford 2019-04-03 09:24:29 +02:00 committed by Commit Bot
parent ead412ecde
commit 72269e3fa4
13 changed files with 85 additions and 47 deletions

View File

@ -2,6 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
struct Arguments {
const frame: FrameWithArguments;
const base: RawPtr;
const length: intptr;
}
extern operator '[]' macro GetArgumentValue(Arguments, intptr): Object;
extern macro GetFrameArguments(FrameWithArguments, intptr): Arguments;
namespace arguments {
struct ArgumentsInfo {

View File

@ -58,9 +58,8 @@ namespace array_lastindexof {
return -1;
}
macro GetFromIndex(
context: Context, length: Number,
arguments: constexpr Arguments): Number {
macro GetFromIndex(context: Context, length: Number, arguments: Arguments):
Number {
// 4. If fromIndex is present, let n be ? ToInteger(fromIndex);
// else let n be len - 1.
const n: Number = arguments.length < 2 ?

View File

@ -10,7 +10,7 @@ namespace array_of {
const len: Smi = Convert<Smi>(arguments.length);
// 2. Let items be the List of arguments passed to this function.
const items: constexpr Arguments = arguments;
const items: Arguments = arguments;
// 3. Let C be the this value.
const c: Object = receiver;

View File

@ -6,7 +6,7 @@ namespace array_shift {
extern builtin ArrayShift(Context, JSFunction, Object, int32);
macro TryFastArrayShift(implicit context: Context)(
receiver: Object, arguments: constexpr Arguments): Object
receiver: Object, arguments: Arguments): Object
labels Slow {
const array: FastJSArray = Cast<FastJSArray>(receiver) otherwise Slow;
let witness = NewFastJSArrayWitness(array);

View File

@ -53,7 +53,7 @@ namespace array_splice {
macro FastSplice<FixedArrayType: type, ElementType: type>(implicit context:
Context)(
args: constexpr Arguments, a: JSArray, length: Smi, newLength: Smi,
args: Arguments, a: JSArray, length: Smi, newLength: Smi,
lengthDelta: Smi, actualStart: Smi, insertCount: Smi,
actualDeleteCount: Smi): void labels Bailout {
// Make sure elements are writable.
@ -95,7 +95,8 @@ namespace array_splice {
if (insertCount > 0) {
const typedNewElements: FixedArrayType =
UnsafeCast<FixedArrayType>(a.elements);
for (let e: Object of args [2: ]) {
for (let i: intptr = 2; i < args.length; ++i) {
const e: Object = args[i];
// The argument elements were already validated to be an appropriate
// {ElementType} to store in {FixedArrayType}.
typedNewElements[k++] = UnsafeCast<ElementType>(e);
@ -107,7 +108,7 @@ namespace array_splice {
}
transitioning macro FastArraySplice(
context: Context, args: constexpr Arguments, o: JSReceiver,
context: Context, args: Arguments, o: JSReceiver,
originalLengthNumber: Number, actualStartNumber: Number, insertCount: Smi,
actualDeleteCountNumber: Number): Object
labels Bailout {
@ -131,7 +132,8 @@ namespace array_splice {
if (!IsFastElementsKind(elementsKind)) goto Bailout;
const oldElementsKind: ElementsKind = elementsKind;
for (let e: Object of args [2: ]) {
for (let i: intptr = 2; i < args.length; ++i) {
const e: Object = args[i];
if (IsFastSmiElementsKind(elementsKind)) {
if (TaggedIsNotSmi(e)) {
const heapObject: HeapObject = UnsafeCast<HeapObject>(e);
@ -296,8 +298,8 @@ namespace array_splice {
}
transitioning macro SlowSplice(
context: Context, arguments: constexpr Arguments, o: JSReceiver,
len: Number, actualStart: Number, insertCount: Smi,
context: Context, arguments: Arguments, o: JSReceiver, len: Number,
actualStart: Number, insertCount: Smi,
actualDeleteCount: Number): Object {
const affected: Number = len - actualStart - actualDeleteCount;
@ -332,7 +334,8 @@ namespace array_splice {
// a. Remove the first element from items and let E be the value of that
// element.
if (arguments.length > 2) {
for (let e: Object of arguments [2: ]) {
for (let i: intptr = 2; i < arguments.length; ++i) {
const e: Object = arguments[i];
// b. Perform ? Set(O, ! ToString(k), E, true).
SetProperty(o, k, e);

View File

@ -6,7 +6,7 @@ namespace array_unshift {
extern builtin ArrayUnshift(Context, JSFunction, Object, int32);
macro TryFastArrayUnshift(
context: Context, receiver: Object, arguments: constexpr Arguments): never
context: Context, receiver: Object, arguments: Arguments): never
labels Slow {
const array: FastJSArray = Cast<FastJSArray>(receiver) otherwise Slow;
array::EnsureWriteableFastElements(array);
@ -21,8 +21,7 @@ namespace array_unshift {
}
transitioning macro GenericArrayUnshift(
context: Context, receiver: Object,
arguments: constexpr Arguments): Number {
context: Context, receiver: Object, arguments: Arguments): Number {
// 1. Let O be ? ToObject(this value).
const object: JSReceiver = ToObject_Inline(context, receiver);

View File

@ -17,7 +17,6 @@
#include 'src/objects/module.h'
#include 'src/objects/stack-frame-info.h'
type Arguments constexpr 'CodeStubArguments*';
type void;
type never;
@ -1153,10 +1152,6 @@ extern operator '.length_intptr' macro LoadStringLengthAsWord(String): intptr;
extern operator '.length_uint32' macro LoadStringLengthAsWord32(String): uint32;
extern operator '.length_smi' macro LoadStringLengthAsSmi(String): Smi;
extern operator '.length' macro GetArgumentsLength(constexpr Arguments): intptr;
extern operator '[]' macro GetArgumentValue(
constexpr Arguments, intptr): Object;
extern builtin StringAdd_CheckNone(implicit context: Context)(
String, String): String;
operator '+' macro StringAdd(implicit context: Context)(

View File

@ -33,7 +33,8 @@ type FrameBase extends RawPtr constexpr 'void*';
type StandardFrame extends FrameBase constexpr 'void*';
type ArgumentsAdaptorFrame extends FrameBase constexpr 'void*';
type StubFrame extends FrameBase constexpr 'void*';
type Frame = ArgumentsAdaptorFrame | StandardFrame | StubFrame;
type FrameWithArguments = StandardFrame | ArgumentsAdaptorFrame;
type Frame = FrameWithArguments | StubFrame;
extern macro LoadFramePointer(): Frame;
extern macro LoadParentFramePointer(): Frame;

View File

@ -13225,26 +13225,26 @@ CodeStubArguments::CodeStubArguments(
argc_mode_(param_mode),
receiver_mode_(receiver_mode),
argc_(argc),
arguments_(),
base_(),
fp_(fp != nullptr ? fp : assembler_->LoadFramePointer()) {
Node* offset = assembler_->ElementOffsetFromIndex(
argc_, SYSTEM_POINTER_ELEMENTS, param_mode,
(StandardFrameConstants::kFixedSlotCountAboveFp - 1) *
kSystemPointerSize);
arguments_ =
assembler_->UncheckedCast<WordT>(assembler_->IntPtrAdd(fp_, offset));
base_ =
assembler_->UncheckedCast<RawPtrT>(assembler_->IntPtrAdd(fp_, offset));
}
TNode<Object> CodeStubArguments::GetReceiver() const {
DCHECK_EQ(receiver_mode_, ReceiverMode::kHasReceiver);
return assembler_->UncheckedCast<Object>(assembler_->LoadFullTagged(
arguments_, assembler_->IntPtrConstant(kSystemPointerSize)));
base_, assembler_->IntPtrConstant(kSystemPointerSize)));
}
void CodeStubArguments::SetReceiver(TNode<Object> object) const {
DCHECK_EQ(receiver_mode_, ReceiverMode::kHasReceiver);
assembler_->StoreFullTaggedNoWriteBarrier(
arguments_, assembler_->IntPtrConstant(kSystemPointerSize), object);
base_, assembler_->IntPtrConstant(kSystemPointerSize), object);
}
TNode<WordT> CodeStubArguments::AtIndexPtr(
@ -13254,7 +13254,7 @@ TNode<WordT> CodeStubArguments::AtIndexPtr(
assembler_->IntPtrOrSmiConstant(0, mode), index, mode);
Node* offset = assembler_->ElementOffsetFromIndex(
negated_index, SYSTEM_POINTER_ELEMENTS, mode, 0);
return assembler_->IntPtrAdd(assembler_->UncheckedCast<IntPtrT>(arguments_),
return assembler_->IntPtrAdd(assembler_->UncheckedCast<IntPtrT>(base_),
offset);
}
@ -13326,10 +13326,10 @@ void CodeStubArguments::ForEach(
last = argc_;
}
Node* start = assembler_->IntPtrSub(
assembler_->UncheckedCast<IntPtrT>(arguments_),
assembler_->UncheckedCast<IntPtrT>(base_),
assembler_->ElementOffsetFromIndex(first, SYSTEM_POINTER_ELEMENTS, mode));
Node* end = assembler_->IntPtrSub(
assembler_->UncheckedCast<IntPtrT>(arguments_),
assembler_->UncheckedCast<IntPtrT>(base_),
assembler_->ElementOffsetFromIndex(last, SYSTEM_POINTER_ELEMENTS, mode));
assembler_->BuildFastLoop(
vars, start, end,
@ -13676,13 +13676,15 @@ Node* CodeStubAssembler::CheckEnumCache(Node* receiver, Label* if_empty,
return receiver_map;
}
TNode<IntPtrT> CodeStubAssembler::GetArgumentsLength(CodeStubArguments* args) {
return args->GetLength();
TNode<Object> CodeStubAssembler::GetArgumentValue(
BaseBuiltinsFromDSLAssembler::Arguments args, TNode<IntPtrT> index) {
return CodeStubArguments(this, args).GetOptionalArgumentValue(index);
}
TNode<Object> CodeStubAssembler::GetArgumentValue(CodeStubArguments* args,
TNode<IntPtrT> index) {
return args->GetOptionalArgumentValue(index);
BaseBuiltinsFromDSLAssembler::Arguments CodeStubAssembler::GetFrameArguments(
TNode<RawPtrT> frame, TNode<IntPtrT> argc) {
return CodeStubArguments(this, argc, frame, INTPTR_PARAMETERS)
.GetTorqueArguments();
}
void CodeStubAssembler::Print(const char* s) {

View File

@ -3206,8 +3206,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
Label* if_fast, Label* if_slow);
Node* CheckEnumCache(Node* receiver, Label* if_empty, Label* if_runtime);
TNode<IntPtrT> GetArgumentsLength(CodeStubArguments* args);
TNode<Object> GetArgumentValue(CodeStubArguments* args, TNode<IntPtrT> index);
TNode<Object> GetArgumentValue(BaseBuiltinsFromDSLAssembler::Arguments args,
TNode<IntPtrT> index);
BaseBuiltinsFromDSLAssembler::Arguments GetFrameArguments(
TNode<RawPtrT> frame, TNode<IntPtrT> argc);
// Support for printf-style debugging
void Print(const char* s);
@ -3499,6 +3502,17 @@ class CodeStubArguments {
CodeStubAssembler::ParameterMode param_mode,
ReceiverMode receiver_mode = ReceiverMode::kHasReceiver);
// Used by Torque to construct arguments based on a Torque-defined
// struct of values.
CodeStubArguments(CodeStubAssembler* assembler,
BaseBuiltinsFromDSLAssembler::Arguments torque_arguments)
: assembler_(assembler),
argc_mode_(CodeStubAssembler::INTPTR_PARAMETERS),
receiver_mode_(ReceiverMode::kHasReceiver),
argc_(torque_arguments.length),
base_(torque_arguments.base),
fp_(torque_arguments.frame) {}
TNode<Object> GetReceiver() const;
// Replaces receiver argument on the expression stack. Should be used only
// for manipulating arguments in trampoline builtins before tail calling
@ -3528,6 +3542,13 @@ class CodeStubArguments {
return argc_;
}
BaseBuiltinsFromDSLAssembler::Arguments GetTorqueArguments() const {
DCHECK_EQ(argc_mode_, CodeStubAssembler::INTPTR_PARAMETERS);
return BaseBuiltinsFromDSLAssembler::Arguments{
assembler_->UncheckedCast<RawPtrT>(fp_), base_,
assembler_->UncheckedCast<IntPtrT>(argc_)};
}
TNode<Object> GetOptionalArgumentValue(TNode<IntPtrT> index) {
return GetOptionalArgumentValue(index, assembler_->UndefinedConstant());
}
@ -3565,7 +3586,7 @@ class CodeStubArguments {
CodeStubAssembler::ParameterMode argc_mode_;
ReceiverMode receiver_mode_;
Node* argc_;
TNode<WordT> arguments_;
TNode<RawPtrT> base_;
Node* fp_;
};

View File

@ -650,7 +650,7 @@ void CSAGenerator::EmitInstruction(const GotoExternalInstruction& instruction,
void CSAGenerator::EmitInstruction(const ReturnInstruction& instruction,
Stack<std::string>* stack) {
if (*linkage_ == Builtin::kVarArgsJavaScript) {
out_ << " " << ARGUMENTS_VARIABLE_STRING << "->PopAndReturn(";
out_ << " " << ARGUMENTS_VARIABLE_STRING << ".PopAndReturn(";
} else {
out_ << " CodeStubAssembler(state_).Return(";
}

View File

@ -489,21 +489,29 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
DCHECK(signature.parameter_types.var_args);
source_out()
<< " Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);\n";
source_out() << " CodeStubArguments arguments_impl(this, "
"ChangeInt32ToIntPtr(argc));\n";
std::string parameter1 = AddParameter(
1, builtin, &parameters, &parameter_types, &parameter_bindings);
source_out()
<< " TNode<IntPtrT> arguments_length(ChangeInt32ToIntPtr(argc));\n";
source_out() << " TNode<RawPtrT> arguments_frame = "
"UncheckedCast<RawPtrT>(LoadFramePointer());\n";
source_out() << " BaseBuiltinsFromDSLAssembler::Arguments "
"torque_arguments(GetFrameArguments(arguments_frame, "
"arguments_length));\n";
source_out() << " CodeStubArguments arguments(this, torque_arguments);\n";
source_out() << " TNode<Object> " << parameter1
<< " = arguments_impl.GetReceiver();\n";
source_out() << "auto " << CSAGenerator::ARGUMENTS_VARIABLE_STRING
<< " = &arguments_impl;\n";
source_out() << "USE(arguments);\n";
<< " = arguments.GetReceiver();\n";
source_out() << "USE(" << parameter1 << ");\n";
parameters.Push("torque_arguments.frame");
parameters.Push("torque_arguments.base");
parameters.Push("torque_arguments.length");
const Type* arguments_type = TypeOracle::GetArgumentsType();
StackRange range = parameter_types.PushMany(LowerType(arguments_type));
parameter_bindings.Add(
*signature.arguments_variable,
LocalValue{true,
VisitResult(TypeOracle::GetArgumentsType(), "arguments")});
LocalValue{true, VisitResult(arguments_type, range)});
first = 2;
}

View File

@ -25,7 +25,7 @@ static const char* const CONSTEXPR_BOOL_TYPE_STRING = "constexpr bool";
static const char* const CONSTEXPR_INTPTR_TYPE_STRING = "constexpr intptr";
static const char* const BOOL_TYPE_STRING = "bool";
static const char* const VOID_TYPE_STRING = "void";
static const char* const ARGUMENTS_TYPE_STRING = "constexpr Arguments";
static const char* const ARGUMENTS_TYPE_STRING = "Arguments";
static const char* const CONTEXT_TYPE_STRING = "Context";
static const char* const MAP_TYPE_STRING = "Map";
static const char* const OBJECT_TYPE_STRING = "Object";