Skip to content

Commit fe99841

Browse files
targosMylesBorins
authored andcommitted
deps: V8: backport 07ee86a5a28b
Original commit message: PPC: allow for calling CFunctions without function descriptors on AIX. The calling conventions on AIX uses function descriptors, which means that pointers to functions do not point to code, but instead point to metadata about them. When calling JITed code, we must assure to use function descriptors instead of raw pointers when needed. Before this CL 213504b, all CallCFunction on AIX were guaranteed to have function descriptors. Starting form the CL mentioned above, CallCFunction can also Jump to a Trampoline which does not have a function descriptor, hence a new "CallCFunctionWithoutFunctionDescriptor" method is proposed to deal with this issue. BUG= v8:9766 Change-Id: I9343c31c812f5d4dda8503a5adf024b24dbde072 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1825961 Commit-Queue: Milad Farazmand <miladfar@ca.ibm.com> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Cr-Commit-Position: refs/heads/master@{#64357} Refs: v8/v8@07ee86a Backport-PR-URL: #30513 PR-URL: #30020 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent 5131bbe commit fe99841

19 files changed

+138
-68
lines changed

common.gypi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939

4040
# Reset this number to 0 on major V8 upgrades.
4141
# Increment by one for each non-official patch applied to deps/v8.
42-
'v8_embedder_string': '-node.15',
42+
'v8_embedder_string': '-node.16',
4343

4444
##### V8 defaults for Node.js #####
4545

deps/v8/src/builtins/builtins-regexp-gen.cc

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -605,13 +605,18 @@ TNode<HeapObject> RegExpBuiltinsAssembler::RegExpExecInternal(
605605

606606
TNode<RawPtrT> code_entry = LoadCodeObjectEntry(code);
607607

608-
TNode<Int32T> result = UncheckedCast<Int32T>(CallCFunction(
609-
code_entry, retval_type, std::make_pair(arg0_type, arg0),
610-
std::make_pair(arg1_type, arg1), std::make_pair(arg2_type, arg2),
611-
std::make_pair(arg3_type, arg3), std::make_pair(arg4_type, arg4),
612-
std::make_pair(arg5_type, arg5), std::make_pair(arg6_type, arg6),
613-
std::make_pair(arg7_type, arg7), std::make_pair(arg8_type, arg8),
614-
std::make_pair(arg9_type, arg9)));
608+
// AIX uses function descriptors on CFunction calls. code_entry in this case
609+
// may also point to a Regex interpreter entry trampoline which does not
610+
// have a function descriptor. This method is ineffective on other platforms
611+
// and is equivalent to CallCFunction.
612+
TNode<Int32T> result =
613+
UncheckedCast<Int32T>(CallCFunctionWithoutFunctionDescriptor(
614+
code_entry, retval_type, std::make_pair(arg0_type, arg0),
615+
std::make_pair(arg1_type, arg1), std::make_pair(arg2_type, arg2),
616+
std::make_pair(arg3_type, arg3), std::make_pair(arg4_type, arg4),
617+
std::make_pair(arg5_type, arg5), std::make_pair(arg6_type, arg6),
618+
std::make_pair(arg7_type, arg7), std::make_pair(arg8_type, arg8),
619+
std::make_pair(arg9_type, arg9)));
615620

616621
// Check the result.
617622
// We expect exactly one result since we force the called regexp to behave

deps/v8/src/codegen/ppc/assembler-ppc.cc

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,20 +1121,6 @@ void Assembler::divdu(Register dst, Register src1, Register src2, OEBit o,
11211121
}
11221122
#endif
11231123

1124-
// Function descriptor for AIX.
1125-
// Code address skips the function descriptor "header".
1126-
// TOC and static chain are ignored and set to 0.
1127-
void Assembler::function_descriptor() {
1128-
if (ABI_USES_FUNCTION_DESCRIPTORS) {
1129-
Label instructions;
1130-
DCHECK_EQ(pc_offset(), 0);
1131-
emit_label_addr(&instructions);
1132-
dp(0);
1133-
dp(0);
1134-
bind(&instructions);
1135-
}
1136-
}
1137-
11381124
int Assembler::instructions_required_for_mov(Register dst,
11391125
const Operand& src) const {
11401126
bool canOptimize =

deps/v8/src/codegen/ppc/assembler-ppc.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -840,8 +840,6 @@ class Assembler : public AssemblerBase {
840840
void mtfprwa(DoubleRegister dst, Register src);
841841
#endif
842842

843-
void function_descriptor();
844-
845843
// Exception-generating instructions and debugging support
846844
void stop(Condition cond = al, int32_t code = kDefaultStopCode,
847845
CRegister cr = cr7);

deps/v8/src/codegen/ppc/constants-ppc.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ namespace internal {
6060
// TODO(sigurds): Change this value once we use relative jumps.
6161
constexpr size_t kMaxPCRelativeCodeRangeInMB = 0;
6262

63+
// Used to encode a boolean value when emitting 32 bit
64+
// opcodes which will indicate the presence of function descriptors
65+
constexpr int kHasFunctionDescriptorBitShift = 9;
66+
constexpr int kHasFunctionDescriptorBitMask = 1
67+
<< kHasFunctionDescriptorBitShift;
68+
6369
// Number of registers
6470
const int kNumRegisters = 32;
6571

deps/v8/src/codegen/ppc/macro-assembler-ppc.cc

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,12 @@ void TurboAssembler::Jump(const ExternalReference& reference) {
209209
UseScratchRegisterScope temps(this);
210210
Register scratch = temps.Acquire();
211211
Move(scratch, reference);
212+
if (ABI_USES_FUNCTION_DESCRIPTORS) {
213+
// AIX uses a function descriptor. When calling C code be
214+
// aware of this descriptor and pick up values from it.
215+
LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(scratch, kPointerSize));
216+
LoadP(scratch, MemOperand(scratch, 0));
217+
}
212218
Jump(scratch);
213219
}
214220

@@ -1930,28 +1936,35 @@ void TurboAssembler::MovToFloatParameters(DoubleRegister src1,
19301936

19311937
void TurboAssembler::CallCFunction(ExternalReference function,
19321938
int num_reg_arguments,
1933-
int num_double_arguments) {
1939+
int num_double_arguments,
1940+
bool has_function_descriptor) {
19341941
Move(ip, function);
1935-
CallCFunctionHelper(ip, num_reg_arguments, num_double_arguments);
1942+
CallCFunctionHelper(ip, num_reg_arguments, num_double_arguments,
1943+
has_function_descriptor);
19361944
}
19371945

19381946
void TurboAssembler::CallCFunction(Register function, int num_reg_arguments,
1939-
int num_double_arguments) {
1940-
CallCFunctionHelper(function, num_reg_arguments, num_double_arguments);
1947+
int num_double_arguments,
1948+
bool has_function_descriptor) {
1949+
CallCFunctionHelper(function, num_reg_arguments, num_double_arguments,
1950+
has_function_descriptor);
19411951
}
19421952

19431953
void TurboAssembler::CallCFunction(ExternalReference function,
1944-
int num_arguments) {
1945-
CallCFunction(function, num_arguments, 0);
1954+
int num_arguments,
1955+
bool has_function_descriptor) {
1956+
CallCFunction(function, num_arguments, 0, has_function_descriptor);
19461957
}
19471958

1948-
void TurboAssembler::CallCFunction(Register function, int num_arguments) {
1949-
CallCFunction(function, num_arguments, 0);
1959+
void TurboAssembler::CallCFunction(Register function, int num_arguments,
1960+
bool has_function_descriptor) {
1961+
CallCFunction(function, num_arguments, 0, has_function_descriptor);
19501962
}
19511963

19521964
void TurboAssembler::CallCFunctionHelper(Register function,
19531965
int num_reg_arguments,
1954-
int num_double_arguments) {
1966+
int num_double_arguments,
1967+
bool has_function_descriptor) {
19551968
DCHECK_LE(num_reg_arguments + num_double_arguments, kMaxCParameters);
19561969
DCHECK(has_frame());
19571970

@@ -1976,7 +1989,7 @@ void TurboAssembler::CallCFunctionHelper(Register function,
19761989
// allow preemption, so the return address in the link register
19771990
// stays correct.
19781991
Register dest = function;
1979-
if (ABI_USES_FUNCTION_DESCRIPTORS) {
1992+
if (ABI_USES_FUNCTION_DESCRIPTORS && has_function_descriptor) {
19801993
// AIX/PPC64BE Linux uses a function descriptor. When calling C code be
19811994
// aware of this descriptor and pick up values from it
19821995
LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(function, kPointerSize));

deps/v8/src/codegen/ppc/macro-assembler-ppc.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -350,12 +350,16 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
350350
// garbage collection, since that might move the code and invalidate the
351351
// return address (unless this is somehow accounted for by the called
352352
// function).
353-
void CallCFunction(ExternalReference function, int num_arguments);
354-
void CallCFunction(Register function, int num_arguments);
353+
void CallCFunction(ExternalReference function, int num_arguments,
354+
bool has_function_descriptor = kHasFunctionDescriptor);
355+
void CallCFunction(Register function, int num_arguments,
356+
bool has_function_descriptor = kHasFunctionDescriptor);
355357
void CallCFunction(ExternalReference function, int num_reg_arguments,
356-
int num_double_arguments);
358+
int num_double_arguments,
359+
bool has_function_descriptor = kHasFunctionDescriptor);
357360
void CallCFunction(Register function, int num_reg_arguments,
358-
int num_double_arguments);
361+
int num_double_arguments,
362+
bool has_function_descriptor = kHasFunctionDescriptor);
359363

360364
// Call a runtime routine. This expects {centry} to contain a fitting CEntry
361365
// builtin for the target runtime function and uses an indirect call.
@@ -642,7 +646,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
642646
int CalculateStackPassedWords(int num_reg_arguments,
643647
int num_double_arguments);
644648
void CallCFunctionHelper(Register function, int num_reg_arguments,
645-
int num_double_arguments);
649+
int num_double_arguments,
650+
bool has_function_descriptor);
646651
void CallRecordWriteStub(Register object, Register address,
647652
RememberedSetAction remembered_set_action,
648653
SaveFPRegsMode fp_mode, Handle<Code> code_target,

deps/v8/src/common/globals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ enum TypeofMode : int { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
400400
// Enums used by CEntry.
401401
enum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs };
402402
enum ArgvMode { kArgvOnStack, kArgvInRegister };
403+
enum FunctionDescriptorMode { kNoFunctionDescriptor, kHasFunctionDescriptor };
403404

404405
// This constant is used as an undefined value when passing source positions.
405406
constexpr int kNoSourcePosition = -1;

deps/v8/src/compiler/backend/instruction-selector.cc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2810,10 +2810,17 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
28102810
// Select the appropriate opcode based on the call type.
28112811
InstructionCode opcode = kArchNop;
28122812
switch (call_descriptor->kind()) {
2813-
case CallDescriptor::kCallAddress:
2814-
opcode = kArchCallCFunction | MiscField::encode(static_cast<int>(
2815-
call_descriptor->ParameterCount()));
2813+
case CallDescriptor::kCallAddress: {
2814+
int misc_field = static_cast<int>(call_descriptor->ParameterCount());
2815+
#if defined(_AIX)
2816+
// Highest misc_field bit is used on AIX to indicate if a CFunction call
2817+
// has function descriptor or not.
2818+
misc_field |= call_descriptor->HasFunctionDescriptor()
2819+
<< kHasFunctionDescriptorBitShift;
2820+
#endif
2821+
opcode = kArchCallCFunction | MiscField::encode(misc_field);
28162822
break;
2823+
}
28172824
case CallDescriptor::kCallCodeObject:
28182825
opcode = kArchCallCodeObject | MiscField::encode(flags);
28192826
break;

deps/v8/src/compiler/backend/instruction.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,8 @@ class V8_EXPORT_PRIVATE Instruction final {
807807
size_t output_count, InstructionOperand* outputs,
808808
size_t input_count, InstructionOperand* inputs,
809809
size_t temp_count, InstructionOperand* temps) {
810-
DCHECK_LE(0, opcode);
810+
// TODO(9872)
811+
// DCHECK_LE(0, opcode);
811812
DCHECK(output_count == 0 || outputs != nullptr);
812813
DCHECK(input_count == 0 || inputs != nullptr);
813814
DCHECK(temp_count == 0 || temps != nullptr);

0 commit comments

Comments
 (0)