Skip to content

Commit a1be327

Browse files
Milad FarazmandMylesBorins
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 <[email protected]> Reviewed-by: Michael Starzinger <[email protected]> Reviewed-by: Jakob Gruber <[email protected]> Cr-Commit-Position: refs/heads/master@{#64357} Refs: v8/v8@07ee86a PR-URL: #32619 Refs: v8/v8@07ee86a Reviewed-By: Richard Lau <[email protected]> Reviewed-By: Michael Dawson <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]>
1 parent e88960d commit a1be327

19 files changed

+139
-59
lines changed

common.gypi

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

3939
# Reset this number to 0 on major V8 upgrades.
4040
# Increment by one for each non-official patch applied to deps/v8.
41-
'v8_embedder_string': '-node.33',
41+
'v8_embedder_string': '-node.34',
4242

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

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

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

604604
TNode<RawPtrT> code_entry = LoadCodeObjectEntry(code);
605605

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

614619
// Check the result.
615620
// 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
@@ -839,8 +839,6 @@ class Assembler : public AssemblerBase {
839839
void mtfprwa(DoubleRegister dst, Register src);
840840
#endif
841841

842-
void function_descriptor();
843-
844842
// Exception-generating instructions and debugging support
845843
void stop(Condition cond = al, int32_t code = kDefaultStopCode,
846844
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

@@ -1931,28 +1937,35 @@ void TurboAssembler::MovToFloatParameters(DoubleRegister src1,
19311937

19321938
void TurboAssembler::CallCFunction(ExternalReference function,
19331939
int num_reg_arguments,
1934-
int num_double_arguments) {
1940+
int num_double_arguments,
1941+
bool has_function_descriptor) {
19351942
Move(ip, function);
1936-
CallCFunctionHelper(ip, num_reg_arguments, num_double_arguments);
1943+
CallCFunctionHelper(ip, num_reg_arguments, num_double_arguments,
1944+
has_function_descriptor);
19371945
}
19381946

19391947
void TurboAssembler::CallCFunction(Register function, int num_reg_arguments,
1940-
int num_double_arguments) {
1941-
CallCFunctionHelper(function, num_reg_arguments, num_double_arguments);
1948+
int num_double_arguments,
1949+
bool has_function_descriptor) {
1950+
CallCFunctionHelper(function, num_reg_arguments, num_double_arguments,
1951+
has_function_descriptor);
19421952
}
19431953

19441954
void TurboAssembler::CallCFunction(ExternalReference function,
1945-
int num_arguments) {
1946-
CallCFunction(function, num_arguments, 0);
1955+
int num_arguments,
1956+
bool has_function_descriptor) {
1957+
CallCFunction(function, num_arguments, 0, has_function_descriptor);
19471958
}
19481959

1949-
void TurboAssembler::CallCFunction(Register function, int num_arguments) {
1950-
CallCFunction(function, num_arguments, 0);
1960+
void TurboAssembler::CallCFunction(Register function, int num_arguments,
1961+
bool has_function_descriptor) {
1962+
CallCFunction(function, num_arguments, 0, has_function_descriptor);
19511963
}
19521964

19531965
void TurboAssembler::CallCFunctionHelper(Register function,
19541966
int num_reg_arguments,
1955-
int num_double_arguments) {
1967+
int num_double_arguments,
1968+
bool has_function_descriptor) {
19561969
DCHECK_LE(num_reg_arguments + num_double_arguments, kMaxCParameters);
19571970
DCHECK(has_frame());
19581971

@@ -1977,7 +1990,7 @@ void TurboAssembler::CallCFunctionHelper(Register function,
19771990
// allow preemption, so the return address in the link register
19781991
// stays correct.
19791992
Register dest = function;
1980-
if (ABI_USES_FUNCTION_DESCRIPTORS) {
1993+
if (ABI_USES_FUNCTION_DESCRIPTORS && has_function_descriptor) {
19811994
// AIX/PPC64BE Linux uses a function descriptor. When calling C code be
19821995
// aware of this descriptor and pick up values from it
19831996
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
@@ -404,6 +404,7 @@ enum TypeofMode : int { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
404404
// Enums used by CEntry.
405405
enum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs };
406406
enum ArgvMode { kArgvOnStack, kArgvInRegister };
407+
enum FunctionDescriptorMode { kNoFunctionDescriptor, kHasFunctionDescriptor };
407408

408409
// This constant is used as an undefined value when passing source positions.
409410
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
@@ -2786,10 +2786,17 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
27862786
// Select the appropriate opcode based on the call type.
27872787
InstructionCode opcode = kArchNop;
27882788
switch (call_descriptor->kind()) {
2789-
case CallDescriptor::kCallAddress:
2790-
opcode = kArchCallCFunction | MiscField::encode(static_cast<int>(
2791-
call_descriptor->ParameterCount()));
2789+
case CallDescriptor::kCallAddress: {
2790+
int misc_field = static_cast<int>(call_descriptor->ParameterCount());
2791+
#if defined(_AIX)
2792+
// Highest misc_field bit is used on AIX to indicate if a CFunction call
2793+
// has function descriptor or not.
2794+
misc_field |= call_descriptor->HasFunctionDescriptor()
2795+
<< kHasFunctionDescriptorBitShift;
2796+
#endif
2797+
opcode = kArchCallCFunction | MiscField::encode(misc_field);
27922798
break;
2799+
}
27932800
case CallDescriptor::kCallCodeObject:
27942801
opcode = kArchCallCodeObject | MiscField::encode(flags);
27952802
break;

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,8 @@ class V8_EXPORT_PRIVATE Instruction final {
826826
size_t output_count, InstructionOperand* outputs,
827827
size_t input_count, InstructionOperand* inputs,
828828
size_t temp_count, InstructionOperand* temps) {
829-
DCHECK_LE(0, opcode);
829+
// TODO(9872)
830+
// DCHECK_LE(0, opcode);
830831
DCHECK(output_count == 0 || outputs != nullptr);
831832
DCHECK(input_count == 0 || inputs != nullptr);
832833
DCHECK(temp_count == 0 || temps != nullptr);

0 commit comments

Comments
 (0)