Commit 72269e3f authored by Daniel Clifford's avatar Daniel Clifford Committed by Commit Bot

[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: 's avatarSigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60597}
parent ead412ec
......@@ -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 {
......
......@@ -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 ?
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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)(
......
......@@ -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;
......
......@@ -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) {
......
......@@ -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_;
};
......
......@@ -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(";
}
......
......@@ -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;
}
......
......@@ -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";
......
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