Commit a74afec6 authored by Daniel Clifford's avatar Daniel Clifford Committed by Commit Bot

[builtins] Port GetArgumentsFrameAndCount to Torque

In the process, add the bint type (which stands for Best-INTeger),
which implements Torque's idea of CSA's ParameterMode. It maps to
a different type on 32-bit (Smi) and 64-bit (intptr). There are
convert operators that are either no-ops or conversions
to-and-from Smi and intptrs on the each platform, depending on
the underlying type for bint. This allows Torque code to git most
of the benefits of ParameterMode without having to explicitly
pass around the mode, since it is almost always OptimalMode anyways.

Change-Id: I92e08adc1d79cb3e24576c96f9734aec1af54162
Reviewed-on: https://chromium-review.googlesource.com/c/1361160
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58253}
parent 00d6c667
......@@ -952,6 +952,8 @@ action("postmortem-metadata") {
torque_files = [
"src/builtins/base.tq",
"src/builtins/frames.tq",
"src/builtins/arguments.tq",
"src/builtins/array.tq",
"src/builtins/array-copywithin.tq",
"src/builtins/array-foreach.tq",
......@@ -964,7 +966,6 @@ torque_files = [
"src/builtins/array-unshift.tq",
"src/builtins/collections.tq",
"src/builtins/data-view.tq",
"src/builtins/frames.tq",
"src/builtins/object.tq",
"src/builtins/object-fromentries.tq",
"src/builtins/iterator.tq",
......@@ -975,6 +976,7 @@ torque_files = [
torque_namespaces = [
"base",
"arguments",
"array",
"collections",
"iterator",
......
// 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.
namespace arguments {
struct ArgumentsInfo {
frame: Frame;
argument_count: bint;
formal_parameter_count: bint;
}
// Calculates and returns the frame pointer, argument count and formal
// parameter count to be used to access a function's parameters, taking
// argument adapter frames into account.
//
// TODO(danno):
// This macro is should only be used in builtins that can be called from
// interpreted or JITted code, not from CSA/Torque builtins (the number of
// returned formal parameters would be wrong).
// It is difficult to actually check/assert this, since interpreted or JITted
// frames are StandardFrames, but so are hand-written builtins. Doing that
// more refined check would be prohibitively expensive.
macro GetArgumentsFrameAndCount(implicit context: Context)(f: JSFunction):
ArgumentsInfo {
let frame: Frame = LoadParentFramePointer();
assert(frame.function == f);
const shared: SharedFunctionInfo = f.shared_function_info;
const formalParameterCount: bint =
Convert<bint>(shared.formal_parameter_count);
let argumentCount: bint = formalParameterCount;
const adaptor: ArgumentsAdaptorFrame =
Cast<ArgumentsAdaptorFrame>(frame.caller)
otherwise return ArgumentsInfo{frame, argumentCount, formalParameterCount};
return ArgumentsInfo{
adaptor,
Convert<bint>(adaptor.length),
formalParameterCount
};
}
}
......@@ -27,6 +27,7 @@ type uintptr generates 'TNode<UintPtrT>' constexpr 'uintptr_t';
type float32 generates 'TNode<Float32T>' constexpr 'float';
type float64 generates 'TNode<Float64T>' constexpr 'double';
type bool generates 'TNode<BoolT>' constexpr 'bool';
type bint generates 'TNode<BInt>' constexpr 'BInt';
type string constexpr 'const char*';
type int31 extends int32
......@@ -64,7 +65,15 @@ transient type FastJSArrayForCopy extends FastJSArray
transient type FastJSArrayWithNoCustomIteration extends FastJSArray
generates 'TNode<JSArray>';
type SharedFunctionInfo extends HeapObject
generates 'TNode<SharedFunctionInfo>';
type JSFunction extends JSObject generates 'TNode<JSFunction>';
extern operator '.shared_function_info'
macro LoadJSFunctionSharedFunctionInfo(JSFunction): SharedFunctionInfo;
extern operator '.formal_parameter_count'
macro LoadSharedFunctionInfoFormalParameterCount(SharedFunctionInfo): int32;
type JSBoundFunction extends JSObject generates 'TNode<JSBoundFunction>';
type Callable = JSFunction | JSBoundFunction | JSProxy;
type Map extends HeapObject generates 'TNode<Map>';
......@@ -924,6 +933,17 @@ Convert<uintptr, RawPtr>(r: RawPtr): uintptr {
Convert<intptr, RawPtr>(r: RawPtr): intptr {
return Signed(r);
}
Convert<bint, int32>(v: int32): bint {
return IntPtrToBInt(Convert<intptr>(v));
}
extern macro IntPtrToBInt(intptr): bint;
Convert<bint, intptr>(v: intptr): bint {
return IntPtrToBInt(v);
}
extern macro SmiToBInt(Smi): bint;
Convert<bint, Smi>(v: Smi): bint {
return SmiToBInt(v);
}
macro BranchIf<A: type, B: type>(implicit context: Context)(o: B): never
labels True, False {
......
This diff is collapsed.
......@@ -6,6 +6,7 @@
#define V8_BUILTINS_BUILTINS_ARGUMENTS_GEN_H_
#include "src/code-stub-assembler.h"
#include "torque-generated/builtins-arguments-from-dsl-gen.h"
namespace v8 {
namespace internal {
......@@ -14,23 +15,17 @@ typedef compiler::Node Node;
typedef compiler::CodeAssemblerState CodeAssemblerState;
typedef compiler::CodeAssemblerLabel CodeAssemblerLabel;
class ArgumentsBuiltinsAssembler : public CodeStubAssembler {
class ArgumentsBuiltinsAssembler : public CodeStubAssembler,
public ArgumentsBuiltinsFromDSLAssembler {
public:
explicit ArgumentsBuiltinsAssembler(CodeAssemblerState* state)
: CodeStubAssembler(state) {}
: CodeStubAssembler(state), ArgumentsBuiltinsFromDSLAssembler(state) {}
Node* EmitFastNewStrictArguments(Node* context, Node* function);
Node* EmitFastNewSloppyArguments(Node* context, Node* function);
Node* EmitFastNewRestParameter(Node* context, Node* function);
private:
// Calculates and returns the the frame pointer, argument count and formal
// parameter count to be used to access a function's parameters, taking
// argument adapter frames into account. The tuple is of the form:
// <frame_ptr, # parameters actually passed, formal parameter count>
std::tuple<Node*, Node*, Node*> GetArgumentsFrameAndCount(Node* function,
ParameterMode mode);
// Allocates an an arguments (either rest, strict or sloppy) together with the
// FixedArray elements for the arguments and a parameter map (for sloppy
// arguments only). A tuple is returned with pointers to the arguments object,
......
......@@ -34,11 +34,11 @@ type FrameBase extends RawPtr
generates 'TNode<RawPtrT>' constexpr 'void*';
type StandardFrame extends FrameBase
generates 'TNode<RawPtrT>' constexpr 'void*';
type ArgumentsAdapterFrame extends FrameBase
type ArgumentsAdaptorFrame extends FrameBase
generates 'TNode<RawPtrT>' constexpr 'void*';
type StubFrame extends FrameBase
generates 'TNode<RawPtrT>' constexpr 'void*';
type Frame = ArgumentsAdapterFrame | StandardFrame | StubFrame;
type Frame = ArgumentsAdaptorFrame | StandardFrame | StubFrame;
extern macro LoadFramePointer(): Frame;
extern macro LoadParentFramePointer(): Frame;
......@@ -101,7 +101,7 @@ const kArgumentsAdaptorFrameLengthOffset: constexpr int31
generates 'ArgumentsAdaptorFrameConstants::kLengthOffset';
operator '.length'
macro LoadLengthFromAdapterFrame(implicit context: Context)(
f: ArgumentsAdapterFrame): Smi {
f: ArgumentsAdaptorFrame): Smi {
return LoadSmiFromFrame(f, kArgumentsAdaptorFrameLengthOffset);
}
......@@ -129,12 +129,12 @@ Cast<StandardFrame>(implicit context: Context)(f: Frame):
goto CastError;
}
Cast<ArgumentsAdapterFrame>(implicit context: Context)(f: Frame):
ArgumentsAdapterFrame labels CastError {
Cast<ArgumentsAdaptorFrame>(implicit context: Context)(f: Frame):
ArgumentsAdaptorFrame labels CastError {
const t: FrameType =
Cast<FrameType>(f.context_or_frame_type) otherwise CastError;
if (t == ARGUMENTS_ADAPTOR_FRAME) {
return %RawPointerCast<ArgumentsAdapterFrame>(f);
return %RawPointerCast<ArgumentsAdaptorFrame>(f);
}
goto CastError;
}
......
......@@ -276,6 +276,24 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
return value;
}
#if defined(V8_HOST_ARCH_32_BIT)
TNode<Smi> BIntToSmi(TNode<BInt> source) { return source; }
TNode<IntPtrT> BIntToIntPtr(TNode<BInt> source) {
return SmiToIntPtr(source);
}
TNode<BInt> SmiToBInt(TNode<Smi> source) { return source; }
TNode<BInt> IntPtrToBInt(TNode<IntPtrT> source) {
return SmiFromIntPtr(source);
}
#elif defined(V8_HOST_ARCH_64_BIT)
TNode<Smi> BIntToSmi(TNode<BInt> source) { return SmiFromIntPtr(source); }
TNode<IntPtrT> BIntToIntPtr(TNode<BInt> source) { return source; }
TNode<BInt> SmiToBInt(TNode<Smi> source) { return SmiToIntPtr(source); }
TNode<BInt> IntPtrToBInt(TNode<IntPtrT> source) { return source; }
#else
#error Unknown architecture.
#endif
TNode<Smi> TaggedToSmi(TNode<Object> value, Label* fail) {
GotoIf(TaggedIsNotSmi(value), fail);
return UncheckedCast<Smi>(value);
......
......@@ -1691,6 +1691,15 @@ class CodeAssemblerScopedExceptionHandler {
};
} // namespace compiler
#if defined(V8_HOST_ARCH_32_BIT)
typedef Smi BInt;
#elif defined(V8_HOST_ARCH_64_BIT)
typedef IntPtrT BInt;
#else
#error Unknown architecture.
#endif
} // namespace internal
} // namespace v8
......
......@@ -125,8 +125,8 @@ bool IsKeywordLikeName(const std::string& s) {
// naming convention and are those exempt from the normal type convention.
bool IsMachineType(const std::string& s) {
static const char* const machine_types[]{
"void", "never", "int32", "uint32", "int64", "intptr",
"uintptr", "float32", "float64", "bool", "string", "int31"};
"void", "never", "int32", "uint32", "int64", "intptr", "uintptr",
"float32", "float64", "bool", "string", "bint", "int31"};
return std::find(std::begin(machine_types), std::end(machine_types), s) !=
std::end(machine_types);
......
......@@ -681,7 +681,7 @@ namespace test {
case (f: StandardFrame): {
unreachable;
}
case (f: ArgumentsAdapterFrame): {
case (f: ArgumentsAdaptorFrame): {
unreachable;
}
case (f: StubFrame): {
......
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