Commit edbcb4b4 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[csa] Support querying kJSTarget parameter in TFJ builtins.

Bug: v8:7754
Change-Id: I0c74b4025d9e52f3580e2da6bd7ac2b8ec2ee620
Reviewed-on: https://chromium-review.googlesource.com/1104469
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarDaniel Clifford <danno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53969}
parent f2695f73
......@@ -1007,8 +1007,10 @@ TF_BUILTIN(ArrayPrototypePop, CodeStubAssembler) {
BIND(&runtime);
{
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
// We are not using Parameter(Descriptor::kJSTarget) and loading the value
// from the current frame here in order to reduce register pressure on the
// fast path.
TNode<JSFunction> target = LoadTargetFromFrame();
TailCallBuiltin(Builtins::kArrayPop, context, target, UndefinedConstant(),
argc);
}
......@@ -1139,8 +1141,10 @@ TF_BUILTIN(ArrayPrototypePush, CodeStubAssembler) {
BIND(&runtime);
{
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
// We are not using Parameter(Descriptor::kJSTarget) and loading the value
// from the current frame here in order to reduce register pressure on the
// fast path.
TNode<JSFunction> target = LoadTargetFromFrame();
TailCallBuiltin(Builtins::kArrayPush, context, target, UndefinedConstant(),
argc);
}
......@@ -1636,8 +1640,10 @@ TF_BUILTIN(ArrayPrototypeShift, CodeStubAssembler) {
BIND(&runtime);
{
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
// We are not using Parameter(Descriptor::kJSTarget) and loading the value
// from the current frame here in order to reduce register pressure on the
// fast path.
TNode<JSFunction> target = LoadTargetFromFrame();
TailCallBuiltin(Builtins::kArrayShift, context, target, UndefinedConstant(),
argc);
}
......
......@@ -28,8 +28,10 @@ TF_BUILTIN(FastConsoleAssert, CodeStubAssembler) {
BIND(&runtime);
{
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
// We are not using Parameter(Descriptor::kJSTarget) and loading the value
// from the current frame here in order to reduce register pressure on the
// fast path.
TNode<JSFunction> target = LoadTargetFromFrame();
TailCallBuiltin(Builtins::kConsoleAssert, context, target, new_target,
argc);
}
......
......@@ -640,8 +640,7 @@ TF_BUILTIN(ObjectConstructor, ConstructorBuiltinsAssembler) {
Label if_subclass(this, Label::kDeferred), if_notsubclass(this),
return_result(this);
GotoIf(IsUndefined(new_target), &if_notsubclass);
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
TNode<JSFunction> target = CAST(Parameter(Descriptor::kJSTarget));
Branch(WordEqual(new_target, target), &if_notsubclass, &if_subclass);
BIND(&if_subclass);
......@@ -718,8 +717,11 @@ TF_BUILTIN(NumberConstructor, ConstructorBuiltinsAssembler) {
// "%NumberPrototype%", « [[NumberData]] »).
// 5. Set O.[[NumberData]] to n.
// 6. Return O.
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
// We are not using Parameter(Descriptor::kJSTarget) and loading the value
// from the current frame here in order to reduce register pressure on the
// fast path.
TNode<JSFunction> target = LoadTargetFromFrame();
Node* result =
CallBuiltin(Builtins::kFastNewObject, context, target, new_target);
StoreObjectField(result, JSValue::kValueOffset, n_value);
......@@ -735,9 +737,7 @@ TF_BUILTIN(StringConstructor, ConstructorBuiltinsAssembler) {
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
Node* new_target = Parameter(Descriptor::kJSNewTarget);
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
TNode<Object> new_target = CAST(Parameter(Descriptor::kJSNewTarget));
// 1. If no arguments were passed to this function invocation, let s be "".
VARIABLE(var_s, MachineRepresentation::kTagged, EmptyStringConstant());
......@@ -778,6 +778,11 @@ TF_BUILTIN(StringConstructor, ConstructorBuiltinsAssembler) {
BIND(&constructstring);
{
// We are not using Parameter(Descriptor::kJSTarget) and loading the value
// from the current frame here in order to reduce register pressure on the
// fast path.
TNode<JSFunction> target = LoadTargetFromFrame();
Node* result =
CallBuiltin(Builtins::kFastNewObject, context, target, new_target);
StoreObjectField(result, JSValue::kValueOffset, s_value);
......
......@@ -6,6 +6,7 @@
#define V8_BUILTINS_BUILTINS_DESCRIPTORS_H_
#include "src/builtins/builtins.h"
#include "src/compiler/code-assembler.h"
#include "src/interface-descriptors.h"
#include "src/objects/shared-function-info.h"
......@@ -16,7 +17,7 @@ namespace internal {
#define DEFINE_TFJ_INTERFACE_DESCRIPTOR(Name, Argc, ...) \
struct Builtin_##Name##_InterfaceDescriptor { \
enum ParameterIndices { \
kJSTarget = -1, \
kJSTarget = compiler::CodeAssembler::kTargetParameterIndex, \
##__VA_ARGS__, \
kJSNewTarget, \
kJSActualArgumentsCount, \
......@@ -25,6 +26,7 @@ namespace internal {
}; \
static_assert((Argc) == static_cast<uint16_t>(kParameterCount - 4), \
"Inconsistent set of arguments"); \
static_assert(kJSTarget == -1, "Unexpected kJSTarget index value"); \
};
// Define interface descriptors for builtins with StubCall linkage.
......
......@@ -184,10 +184,14 @@ TF_BUILTIN(FastFunctionPrototypeBind, CodeStubAssembler) {
}
BIND(&slow);
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
TailCallBuiltin(Builtins::kFunctionPrototypeBind, context, target, new_target,
argc);
{
// We are not using Parameter(Descriptor::kJSTarget) and loading the value
// from the current frame here in order to reduce register pressure on the
// fast path.
TNode<JSFunction> target = LoadTargetFromFrame();
TailCallBuiltin(Builtins::kFunctionPrototypeBind, context, target,
new_target, argc);
}
}
// ES6 #sec-function.prototype-@@hasinstance
......
......@@ -180,8 +180,7 @@ TF_BUILTIN(DebugBreakTrampoline, CodeStubAssembler) {
TNode<Object> new_target = CAST(Parameter(Descriptor::kJSNewTarget));
TNode<Int32T> arg_count =
UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount));
TNode<JSFunction> function = CAST(LoadFromFrame(
StandardFrameConstants::kFunctionOffset, MachineType::TaggedPointer()));
TNode<JSFunction> function = CAST(Parameter(Descriptor::kJSTarget));
// Check break-at-entry flag on the debug info.
TNode<SharedFunctionInfo> shared =
......
......@@ -2028,7 +2028,7 @@ TF_BUILTIN(PromiseAll, PromiseBuiltinsAssembler) {
TF_BUILTIN(PromiseAllResolveElementClosure, PromiseBuiltinsAssembler) {
TNode<Object> value = CAST(Parameter(Descriptor::kValue));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Node* function = LoadFromFrame(StandardFrameConstants::kFunctionOffset);
TNode<JSFunction> function = CAST(Parameter(Descriptor::kJSTarget));
Label already_called(this, Label::kDeferred), resolve_promise(this);
......
......@@ -757,10 +757,9 @@ TF_BUILTIN(TypedArrayConstructorLazyDeoptContinuation,
// ES #sec-typedarray-constructors
TF_BUILTIN(TypedArrayConstructor, TypedArrayBuiltinsAssembler) {
Node* context = Parameter(Descriptor::kContext);
Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer());
Node* new_target = Parameter(Descriptor::kJSNewTarget);
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<JSFunction> target = CAST(Parameter(Descriptor::kJSTarget));
TNode<Object> new_target = CAST(Parameter(Descriptor::kJSNewTarget));
Node* argc =
ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, argc);
......
......@@ -1337,6 +1337,12 @@ Node* CodeStubAssembler::LoadFromParentFrame(int offset, MachineType rep) {
return Load(rep, frame_pointer, IntPtrConstant(offset));
}
TNode<JSFunction> CodeStubAssembler::LoadTargetFromFrame() {
DCHECK(IsJSFunctionCall());
return CAST(LoadFromFrame(StandardFrameConstants::kFunctionOffset,
MachineType::TaggedPointer()));
}
Node* CodeStubAssembler::LoadBufferObject(Node* buffer, int offset,
MachineType rep) {
return Load(rep, buffer, IntPtrConstant(offset));
......
......@@ -727,6 +727,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* LoadFromParentFrame(int offset,
MachineType rep = MachineType::AnyTagged());
// Load target function from the current JS frame.
// This is an alternative way of getting the target function in addition to
// Parameter(Descriptor::kJSTarget). The latter should be used near the
// beginning of builtin code while the target value is still in the register
// and the former should be used in slow paths in order to reduce register
// pressure on the fast path.
TNode<JSFunction> LoadTargetFromFrame();
// Load an object pointer from a buffer that isn't in the heap.
Node* LoadBufferObject(Node* buffer, int offset,
MachineType rep = MachineType::AnyTagged());
......
......@@ -371,8 +371,14 @@ bool CodeAssembler::IsNullConstant(TNode<Object> node) {
return m.Is(isolate()->factory()->null_value());
}
Node* CodeAssembler::Parameter(int value) {
return raw_assembler()->Parameter(value);
Node* CodeAssembler::Parameter(int index) {
if (index == kTargetParameterIndex) return raw_assembler()->TargetParameter();
return raw_assembler()->Parameter(index);
}
bool CodeAssembler::IsJSFunctionCall() const {
auto call_descriptor = raw_assembler()->call_descriptor();
return call_descriptor->IsJSFunctionCall();
}
TNode<Context> CodeAssembler::GetJSContextParameter() {
......
......@@ -738,6 +738,8 @@ class V8_EXPORT_PRIVATE CodeAssembler {
return UncheckedCast<UintPtrT>(x);
}
static constexpr int kTargetParameterIndex = -1;
Node* Parameter(int value);
TNode<Context> GetJSContextParameter();
......@@ -1197,6 +1199,8 @@ class V8_EXPORT_PRIVATE CodeAssembler {
bool Word32ShiftIsSafe() const;
PoisoningMitigationLevel poisoning_level() const;
bool IsJSFunctionCall() const;
private:
TNode<Object> CallRuntimeImpl(Runtime::FunctionId function,
TNode<Object> context,
......
......@@ -24,12 +24,17 @@ RawMachineAssembler::RawMachineAssembler(
machine_(zone(), word, flags, alignment_requirements),
common_(zone()),
call_descriptor_(call_descriptor),
target_parameter_(nullptr),
parameters_(parameter_count(), zone()),
current_block_(schedule()->start()),
poisoning_level_(poisoning_level) {
int param_count = static_cast<int>(parameter_count());
// Add an extra input for the JSFunction parameter to the start node.
graph->SetStart(graph->NewNode(common_.Start(param_count + 1)));
if (call_descriptor->IsJSFunctionCall()) {
target_parameter_ = AddNode(
common()->Parameter(Linkage::kJSCallClosureParamIndex), graph->start());
}
for (size_t i = 0; i < parameter_count(); ++i) {
parameters_[i] =
AddNode(common()->Parameter(static_cast<int>(i)), graph->start());
......@@ -72,6 +77,10 @@ Schedule* RawMachineAssembler::Export() {
return schedule;
}
Node* RawMachineAssembler::TargetParameter() {
DCHECK_NOT_NULL(target_parameter_);
return target_parameter_;
}
Node* RawMachineAssembler::Parameter(size_t index) {
DCHECK(index < parameter_count());
......
......@@ -742,6 +742,7 @@ class V8_EXPORT_PRIVATE RawMachineAssembler {
}
// Parameters.
Node* TargetParameter();
Node* Parameter(size_t index);
// Pointer utilities.
......@@ -936,6 +937,7 @@ class V8_EXPORT_PRIVATE RawMachineAssembler {
MachineOperatorBuilder machine_;
CommonOperatorBuilder common_;
CallDescriptor* call_descriptor_;
Node* target_parameter_;
NodeVector parameters_;
BasicBlock* current_block_;
PoisoningMitigationLevel poisoning_level_;
......
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