[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:
parent
ead412ecde
commit
72269e3fa4
@ -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, ¶meters, ¶meter_types, ¶meter_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";
|
||||
|
Loading…
Reference in New Issue
Block a user