Commit 07ee86a5 authored by Milad Farazmand's avatar Milad Farazmand Committed by Commit Bot

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 213504b9, 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: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64357}
parent dfd9ceb9
...@@ -613,13 +613,18 @@ TNode<HeapObject> RegExpBuiltinsAssembler::RegExpExecInternal( ...@@ -613,13 +613,18 @@ TNode<HeapObject> RegExpBuiltinsAssembler::RegExpExecInternal(
TNode<RawPtrT> code_entry = LoadCodeObjectEntry(code); TNode<RawPtrT> code_entry = LoadCodeObjectEntry(code);
TNode<Int32T> result = UncheckedCast<Int32T>(CallCFunction( // AIX uses function descriptors on CFunction calls. code_entry in this case
code_entry, retval_type, std::make_pair(arg0_type, arg0), // may also point to a Regex interpreter entry trampoline which does not
std::make_pair(arg1_type, arg1), std::make_pair(arg2_type, arg2), // have a function descriptor. This method is ineffective on other platforms
std::make_pair(arg3_type, arg3), std::make_pair(arg4_type, arg4), // and is equivalent to CallCFunction.
std::make_pair(arg5_type, arg5), std::make_pair(arg6_type, arg6), TNode<Int32T> result =
std::make_pair(arg7_type, arg7), std::make_pair(arg8_type, arg8), UncheckedCast<Int32T>(CallCFunctionWithoutFunctionDescriptor(
std::make_pair(arg9_type, arg9))); code_entry, retval_type, std::make_pair(arg0_type, arg0),
std::make_pair(arg1_type, arg1), std::make_pair(arg2_type, arg2),
std::make_pair(arg3_type, arg3), std::make_pair(arg4_type, arg4),
std::make_pair(arg5_type, arg5), std::make_pair(arg6_type, arg6),
std::make_pair(arg7_type, arg7), std::make_pair(arg8_type, arg8),
std::make_pair(arg9_type, arg9)));
// Check the result. // Check the result.
// We expect exactly one result since we force the called regexp to behave // We expect exactly one result since we force the called regexp to behave
......
...@@ -1121,20 +1121,6 @@ void Assembler::divdu(Register dst, Register src1, Register src2, OEBit o, ...@@ -1121,20 +1121,6 @@ void Assembler::divdu(Register dst, Register src1, Register src2, OEBit o,
} }
#endif #endif
// Function descriptor for AIX.
// Code address skips the function descriptor "header".
// TOC and static chain are ignored and set to 0.
void Assembler::function_descriptor() {
if (ABI_USES_FUNCTION_DESCRIPTORS) {
Label instructions;
DCHECK_EQ(pc_offset(), 0);
emit_label_addr(&instructions);
dp(0);
dp(0);
bind(&instructions);
}
}
int Assembler::instructions_required_for_mov(Register dst, int Assembler::instructions_required_for_mov(Register dst,
const Operand& src) const { const Operand& src) const {
bool canOptimize = bool canOptimize =
......
...@@ -840,8 +840,6 @@ class Assembler : public AssemblerBase { ...@@ -840,8 +840,6 @@ class Assembler : public AssemblerBase {
void mtfprwa(DoubleRegister dst, Register src); void mtfprwa(DoubleRegister dst, Register src);
#endif #endif
void function_descriptor();
// Exception-generating instructions and debugging support // Exception-generating instructions and debugging support
void stop(Condition cond = al, int32_t code = kDefaultStopCode, void stop(Condition cond = al, int32_t code = kDefaultStopCode,
CRegister cr = cr7); CRegister cr = cr7);
......
...@@ -60,6 +60,12 @@ namespace internal { ...@@ -60,6 +60,12 @@ namespace internal {
// TODO(sigurds): Change this value once we use relative jumps. // TODO(sigurds): Change this value once we use relative jumps.
constexpr size_t kMaxPCRelativeCodeRangeInMB = 0; constexpr size_t kMaxPCRelativeCodeRangeInMB = 0;
// Used to encode a boolean value when emitting 32 bit
// opcodes which will indicate the presence of function descriptors
constexpr int kHasFunctionDescriptorBitShift = 9;
constexpr int kHasFunctionDescriptorBitMask = 1
<< kHasFunctionDescriptorBitShift;
// Number of registers // Number of registers
const int kNumRegisters = 32; const int kNumRegisters = 32;
......
...@@ -209,6 +209,12 @@ void TurboAssembler::Jump(const ExternalReference& reference) { ...@@ -209,6 +209,12 @@ void TurboAssembler::Jump(const ExternalReference& reference) {
UseScratchRegisterScope temps(this); UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire(); Register scratch = temps.Acquire();
Move(scratch, reference); Move(scratch, reference);
if (ABI_USES_FUNCTION_DESCRIPTORS) {
// AIX uses a function descriptor. When calling C code be
// aware of this descriptor and pick up values from it.
LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(scratch, kPointerSize));
LoadP(scratch, MemOperand(scratch, 0));
}
Jump(scratch); Jump(scratch);
} }
...@@ -1930,28 +1936,35 @@ void TurboAssembler::MovToFloatParameters(DoubleRegister src1, ...@@ -1930,28 +1936,35 @@ void TurboAssembler::MovToFloatParameters(DoubleRegister src1,
void TurboAssembler::CallCFunction(ExternalReference function, void TurboAssembler::CallCFunction(ExternalReference function,
int num_reg_arguments, int num_reg_arguments,
int num_double_arguments) { int num_double_arguments,
bool has_function_descriptor) {
Move(ip, function); Move(ip, function);
CallCFunctionHelper(ip, num_reg_arguments, num_double_arguments); CallCFunctionHelper(ip, num_reg_arguments, num_double_arguments,
has_function_descriptor);
} }
void TurboAssembler::CallCFunction(Register function, int num_reg_arguments, void TurboAssembler::CallCFunction(Register function, int num_reg_arguments,
int num_double_arguments) { int num_double_arguments,
CallCFunctionHelper(function, num_reg_arguments, num_double_arguments); bool has_function_descriptor) {
CallCFunctionHelper(function, num_reg_arguments, num_double_arguments,
has_function_descriptor);
} }
void TurboAssembler::CallCFunction(ExternalReference function, void TurboAssembler::CallCFunction(ExternalReference function,
int num_arguments) { int num_arguments,
CallCFunction(function, num_arguments, 0); bool has_function_descriptor) {
CallCFunction(function, num_arguments, 0, has_function_descriptor);
} }
void TurboAssembler::CallCFunction(Register function, int num_arguments) { void TurboAssembler::CallCFunction(Register function, int num_arguments,
CallCFunction(function, num_arguments, 0); bool has_function_descriptor) {
CallCFunction(function, num_arguments, 0, has_function_descriptor);
} }
void TurboAssembler::CallCFunctionHelper(Register function, void TurboAssembler::CallCFunctionHelper(Register function,
int num_reg_arguments, int num_reg_arguments,
int num_double_arguments) { int num_double_arguments,
bool has_function_descriptor) {
DCHECK_LE(num_reg_arguments + num_double_arguments, kMaxCParameters); DCHECK_LE(num_reg_arguments + num_double_arguments, kMaxCParameters);
DCHECK(has_frame()); DCHECK(has_frame());
...@@ -1976,7 +1989,7 @@ void TurboAssembler::CallCFunctionHelper(Register function, ...@@ -1976,7 +1989,7 @@ void TurboAssembler::CallCFunctionHelper(Register function,
// allow preemption, so the return address in the link register // allow preemption, so the return address in the link register
// stays correct. // stays correct.
Register dest = function; Register dest = function;
if (ABI_USES_FUNCTION_DESCRIPTORS) { if (ABI_USES_FUNCTION_DESCRIPTORS && has_function_descriptor) {
// AIX/PPC64BE Linux uses a function descriptor. When calling C code be // AIX/PPC64BE Linux uses a function descriptor. When calling C code be
// aware of this descriptor and pick up values from it // aware of this descriptor and pick up values from it
LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(function, kPointerSize)); LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(function, kPointerSize));
......
...@@ -350,12 +350,16 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { ...@@ -350,12 +350,16 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
// garbage collection, since that might move the code and invalidate the // garbage collection, since that might move the code and invalidate the
// return address (unless this is somehow accounted for by the called // return address (unless this is somehow accounted for by the called
// function). // function).
void CallCFunction(ExternalReference function, int num_arguments); void CallCFunction(ExternalReference function, int num_arguments,
void CallCFunction(Register function, int num_arguments); bool has_function_descriptor = kHasFunctionDescriptor);
void CallCFunction(Register function, int num_arguments,
bool has_function_descriptor = kHasFunctionDescriptor);
void CallCFunction(ExternalReference function, int num_reg_arguments, void CallCFunction(ExternalReference function, int num_reg_arguments,
int num_double_arguments); int num_double_arguments,
bool has_function_descriptor = kHasFunctionDescriptor);
void CallCFunction(Register function, int num_reg_arguments, void CallCFunction(Register function, int num_reg_arguments,
int num_double_arguments); int num_double_arguments,
bool has_function_descriptor = kHasFunctionDescriptor);
// Call a runtime routine. This expects {centry} to contain a fitting CEntry // Call a runtime routine. This expects {centry} to contain a fitting CEntry
// builtin for the target runtime function and uses an indirect call. // builtin for the target runtime function and uses an indirect call.
...@@ -642,7 +646,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase { ...@@ -642,7 +646,8 @@ class V8_EXPORT_PRIVATE TurboAssembler : public TurboAssemblerBase {
int CalculateStackPassedWords(int num_reg_arguments, int CalculateStackPassedWords(int num_reg_arguments,
int num_double_arguments); int num_double_arguments);
void CallCFunctionHelper(Register function, int num_reg_arguments, void CallCFunctionHelper(Register function, int num_reg_arguments,
int num_double_arguments); int num_double_arguments,
bool has_function_descriptor);
void CallRecordWriteStub(Register object, Register address, void CallRecordWriteStub(Register object, Register address,
RememberedSetAction remembered_set_action, RememberedSetAction remembered_set_action,
SaveFPRegsMode fp_mode, Handle<Code> code_target, SaveFPRegsMode fp_mode, Handle<Code> code_target,
......
...@@ -400,6 +400,7 @@ enum TypeofMode : int { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF }; ...@@ -400,6 +400,7 @@ enum TypeofMode : int { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
// Enums used by CEntry. // Enums used by CEntry.
enum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs }; enum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs };
enum ArgvMode { kArgvOnStack, kArgvInRegister }; enum ArgvMode { kArgvOnStack, kArgvInRegister };
enum FunctionDescriptorMode { kNoFunctionDescriptor, kHasFunctionDescriptor };
// This constant is used as an undefined value when passing source positions. // This constant is used as an undefined value when passing source positions.
constexpr int kNoSourcePosition = -1; constexpr int kNoSourcePosition = -1;
......
...@@ -2821,10 +2821,17 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) { ...@@ -2821,10 +2821,17 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
// Select the appropriate opcode based on the call type. // Select the appropriate opcode based on the call type.
InstructionCode opcode = kArchNop; InstructionCode opcode = kArchNop;
switch (call_descriptor->kind()) { switch (call_descriptor->kind()) {
case CallDescriptor::kCallAddress: case CallDescriptor::kCallAddress: {
opcode = kArchCallCFunction | MiscField::encode(static_cast<int>( int misc_field = static_cast<int>(call_descriptor->ParameterCount());
call_descriptor->ParameterCount())); #if defined(_AIX)
// Highest misc_field bit is used on AIX to indicate if a CFunction call
// has function descriptor or not.
misc_field |= call_descriptor->HasFunctionDescriptor()
<< kHasFunctionDescriptorBitShift;
#endif
opcode = kArchCallCFunction | MiscField::encode(misc_field);
break; break;
}
case CallDescriptor::kCallCodeObject: case CallDescriptor::kCallCodeObject:
opcode = kArchCallCodeObject | MiscField::encode(flags); opcode = kArchCallCodeObject | MiscField::encode(flags);
break; break;
......
...@@ -807,7 +807,8 @@ class V8_EXPORT_PRIVATE Instruction final { ...@@ -807,7 +807,8 @@ class V8_EXPORT_PRIVATE Instruction final {
size_t output_count, InstructionOperand* outputs, size_t output_count, InstructionOperand* outputs,
size_t input_count, InstructionOperand* inputs, size_t input_count, InstructionOperand* inputs,
size_t temp_count, InstructionOperand* temps) { size_t temp_count, InstructionOperand* temps) {
DCHECK_LE(0, opcode); // TODO(9872)
// DCHECK_LE(0, opcode);
DCHECK(output_count == 0 || outputs != nullptr); DCHECK(output_count == 0 || outputs != nullptr);
DCHECK(input_count == 0 || inputs != nullptr); DCHECK(input_count == 0 || inputs != nullptr);
DCHECK(temp_count == 0 || temps != nullptr); DCHECK(temp_count == 0 || temps != nullptr);
......
...@@ -1019,13 +1019,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1019,13 +1019,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
#endif #endif
break; break;
case kArchCallCFunction: { case kArchCallCFunction: {
int const num_parameters = MiscField::decode(instr->opcode()); int misc_field = MiscField::decode(instr->opcode());
int num_parameters = misc_field;
bool has_function_descriptor = false;
Label start_call; Label start_call;
bool isWasmCapiFunction = bool isWasmCapiFunction =
linkage()->GetIncomingDescriptor()->IsWasmCapiFunction(); linkage()->GetIncomingDescriptor()->IsWasmCapiFunction();
#if defined(_AIX) #if defined(_AIX)
// AIX/PPC64BE Linux uses a function descriptor // AIX/PPC64BE Linux uses a function descriptor
// and emits 2 extra Load instrcutions under CallCFunctionHelper. int kNumParametersMask = kHasFunctionDescriptorBitMask - 1;
num_parameters = kNumParametersMask & misc_field;
has_function_descriptor =
(misc_field & kHasFunctionDescriptorBitMask) != 0;
// AIX emits 2 extra Load instructions under CallCFunctionHelper
// due to having function descriptor.
constexpr int offset = 11 * kInstrSize; constexpr int offset = 11 * kInstrSize;
#else #else
constexpr int offset = 9 * kInstrSize; constexpr int offset = 9 * kInstrSize;
...@@ -1041,10 +1048,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1041,10 +1048,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
} }
if (instr->InputAt(0)->IsImmediate()) { if (instr->InputAt(0)->IsImmediate()) {
ExternalReference ref = i.InputExternalReference(0); ExternalReference ref = i.InputExternalReference(0);
__ CallCFunction(ref, num_parameters); __ CallCFunction(ref, num_parameters, has_function_descriptor);
} else { } else {
Register func = i.InputRegister(0); Register func = i.InputRegister(0);
__ CallCFunction(func, num_parameters); __ CallCFunction(func, num_parameters, has_function_descriptor);
} }
// TODO(miladfar): In the above block, kScratchReg must be populated with // TODO(miladfar): In the above block, kScratchReg must be populated with
// the strictly-correct PC, which is the return address at this spot. The // the strictly-correct PC, which is the return address at this spot. The
......
...@@ -1439,6 +1439,13 @@ Node* CodeAssembler::CallCFunction( ...@@ -1439,6 +1439,13 @@ Node* CodeAssembler::CallCFunction(
return raw_assembler()->CallCFunction(function, return_type, args); return raw_assembler()->CallCFunction(function, return_type, args);
} }
Node* CodeAssembler::CallCFunctionWithoutFunctionDescriptor(
Node* function, MachineType return_type,
std::initializer_list<CodeAssembler::CFunctionArg> args) {
return raw_assembler()->CallCFunctionWithoutFunctionDescriptor(
function, return_type, args);
}
Node* CodeAssembler::CallCFunctionWithCallerSavedRegisters( Node* CodeAssembler::CallCFunctionWithCallerSavedRegisters(
Node* function, MachineType return_type, SaveFPRegsMode mode, Node* function, MachineType return_type, SaveFPRegsMode mode,
std::initializer_list<CodeAssembler::CFunctionArg> args) { std::initializer_list<CodeAssembler::CFunctionArg> args) {
......
...@@ -1103,6 +1103,18 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -1103,6 +1103,18 @@ class V8_EXPORT_PRIVATE CodeAssembler {
return CallCFunction(function, return_type, {cargs...}); return CallCFunction(function, return_type, {cargs...});
} }
// Call to a C function without a function discriptor on AIX.
template <class... CArgs>
Node* CallCFunctionWithoutFunctionDescriptor(Node* function,
MachineType return_type,
CArgs... cargs) {
static_assert(v8::internal::conjunction<
std::is_convertible<CArgs, CFunctionArg>...>::value,
"invalid argument types");
return CallCFunctionWithoutFunctionDescriptor(function, return_type,
{cargs...});
}
// Call to a C function, while saving/restoring caller registers. // Call to a C function, while saving/restoring caller registers.
template <class... CArgs> template <class... CArgs>
Node* CallCFunctionWithCallerSavedRegisters(Node* function, Node* CallCFunctionWithCallerSavedRegisters(Node* function,
...@@ -1151,6 +1163,10 @@ class V8_EXPORT_PRIVATE CodeAssembler { ...@@ -1151,6 +1163,10 @@ class V8_EXPORT_PRIVATE CodeAssembler {
Node* CallCFunction(Node* function, MachineType return_type, Node* CallCFunction(Node* function, MachineType return_type,
std::initializer_list<CFunctionArg> args); std::initializer_list<CFunctionArg> args);
Node* CallCFunctionWithoutFunctionDescriptor(
Node* function, MachineType return_type,
std::initializer_list<CFunctionArg> args);
Node* CallCFunctionWithCallerSavedRegisters( Node* CallCFunctionWithCallerSavedRegisters(
Node* function, MachineType return_type, SaveFPRegsMode mode, Node* function, MachineType return_type, SaveFPRegsMode mode,
std::initializer_list<CFunctionArg> args); std::initializer_list<CFunctionArg> args);
......
...@@ -352,9 +352,18 @@ class V8_EXPORT_PRIVATE CallDescriptor final ...@@ -352,9 +352,18 @@ class V8_EXPORT_PRIVATE CallDescriptor final
SaveFPRegsMode get_save_fp_mode() const { return save_fp_mode_; } SaveFPRegsMode get_save_fp_mode() const { return save_fp_mode_; }
void set_has_function_descriptor(bool has_function_descriptor) {
has_function_descriptor_ = has_function_descriptor;
}
bool HasFunctionDescriptor() const { return has_function_descriptor_; }
private: private:
friend class Linkage; friend class Linkage;
SaveFPRegsMode save_fp_mode_ = kSaveFPRegs; SaveFPRegsMode save_fp_mode_ = kSaveFPRegs;
// AIX has a function descriptor which we will set to true by default
// for all CFunction Calls.
bool has_function_descriptor_ = kHasFunctionDescriptor;
const Kind kind_; const Kind kind_;
const MachineType target_type_; const MachineType target_type_;
......
...@@ -705,7 +705,8 @@ namespace { ...@@ -705,7 +705,8 @@ namespace {
Node* CallCFunctionImpl( Node* CallCFunctionImpl(
RawMachineAssembler* rasm, Node* function, MachineType return_type, RawMachineAssembler* rasm, Node* function, MachineType return_type,
std::initializer_list<RawMachineAssembler::CFunctionArg> args, std::initializer_list<RawMachineAssembler::CFunctionArg> args,
bool caller_saved_regs, SaveFPRegsMode mode) { bool caller_saved_regs, SaveFPRegsMode mode,
bool has_function_descriptor = kHasFunctionDescriptor) {
static constexpr std::size_t kNumCArgs = 10; static constexpr std::size_t kNumCArgs = 10;
MachineSignature::Builder builder(rasm->zone(), 1, args.size()); MachineSignature::Builder builder(rasm->zone(), 1, args.size());
...@@ -719,6 +720,8 @@ Node* CallCFunctionImpl( ...@@ -719,6 +720,8 @@ Node* CallCFunctionImpl(
if (caller_saved_regs) call_descriptor->set_save_fp_mode(mode); if (caller_saved_regs) call_descriptor->set_save_fp_mode(mode);
call_descriptor->set_has_function_descriptor(has_function_descriptor);
base::SmallVector<Node*, kNumCArgs> nodes(args.size() + 1); base::SmallVector<Node*, kNumCArgs> nodes(args.size() + 1);
nodes[0] = function; nodes[0] = function;
std::transform( std::transform(
...@@ -739,6 +742,13 @@ Node* RawMachineAssembler::CallCFunction( ...@@ -739,6 +742,13 @@ Node* RawMachineAssembler::CallCFunction(
kDontSaveFPRegs); kDontSaveFPRegs);
} }
Node* RawMachineAssembler::CallCFunctionWithoutFunctionDescriptor(
Node* function, MachineType return_type,
std::initializer_list<RawMachineAssembler::CFunctionArg> args) {
return CallCFunctionImpl(this, function, return_type, args, false,
kDontSaveFPRegs, kNoFunctionDescriptor);
}
Node* RawMachineAssembler::CallCFunctionWithCallerSavedRegisters( Node* RawMachineAssembler::CallCFunctionWithCallerSavedRegisters(
Node* function, MachineType return_type, SaveFPRegsMode mode, Node* function, MachineType return_type, SaveFPRegsMode mode,
std::initializer_list<RawMachineAssembler::CFunctionArg> args) { std::initializer_list<RawMachineAssembler::CFunctionArg> args) {
......
...@@ -983,6 +983,22 @@ class V8_EXPORT_PRIVATE RawMachineAssembler { ...@@ -983,6 +983,22 @@ class V8_EXPORT_PRIVATE RawMachineAssembler {
Node* CallCFunction(Node* function, MachineType return_type, Node* CallCFunction(Node* function, MachineType return_type,
std::initializer_list<CFunctionArg> args); std::initializer_list<CFunctionArg> args);
// Call to a C function without a function discriptor on AIX.
template <class... CArgs>
Node* CallCFunctionWithoutFunctionDescriptor(Node* function,
MachineType return_type,
CArgs... cargs) {
static_assert(v8::internal::conjunction<
std::is_convertible<CArgs, CFunctionArg>...>::value,
"invalid argument types");
return CallCFunctionWithoutFunctionDescriptor(function, return_type,
{cargs...});
}
Node* CallCFunctionWithoutFunctionDescriptor(
Node* function, MachineType return_type,
std::initializer_list<CFunctionArg> args);
// Call to a C function, while saving/restoring caller registers. // Call to a C function, while saving/restoring caller registers.
template <class... CArgs> template <class... CArgs>
Node* CallCFunctionWithCallerSavedRegisters(Node* function, Node* CallCFunctionWithCallerSavedRegisters(Node* function,
......
...@@ -121,13 +121,6 @@ class GeneratedCode { ...@@ -121,13 +121,6 @@ class GeneratedCode {
return Simulator::current(isolate_)->template Call<Return>( return Simulator::current(isolate_)->template Call<Return>(
reinterpret_cast<Address>(fn_ptr_), args...); reinterpret_cast<Address>(fn_ptr_), args...);
} }
DISABLE_CFI_ICALL Return CallIrregexp(Args... args) {
#if defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN)
FATAL("Generated code execution not possible during cross-compilation.");
#endif // defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN)
return Call(args...);
}
#else #else
DISABLE_CFI_ICALL Return Call(Args... args) { DISABLE_CFI_ICALL Return Call(Args... args) {
...@@ -149,14 +142,6 @@ class GeneratedCode { ...@@ -149,14 +142,6 @@ class GeneratedCode {
return fn_ptr_(args...); return fn_ptr_(args...);
#endif // V8_OS_AIX #endif // V8_OS_AIX
} }
DISABLE_CFI_ICALL Return CallIrregexp(Args... args) {
// When running without a simulator we call the entry directly.
#if defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN)
FATAL("Generated code execution not possible during cross-compilation.");
#endif // defined(V8_TARGET_OS_WIN) && !defined(V8_OS_WIN)
return fn_ptr_(args...);
}
#endif // USE_SIMULATOR #endif // USE_SIMULATOR
private: private:
......
...@@ -113,8 +113,6 @@ RegExpMacroAssemblerPPC::RegExpMacroAssemblerPPC(Isolate* isolate, Zone* zone, ...@@ -113,8 +113,6 @@ RegExpMacroAssemblerPPC::RegExpMacroAssemblerPPC(Isolate* isolate, Zone* zone,
internal_failure_label_() { internal_failure_label_() {
DCHECK_EQ(0, registers_to_save % 2); DCHECK_EQ(0, registers_to_save % 2);
// Because RegExp code respects C ABI, so needs a FD
__ function_descriptor();
__ b(&entry_label_); // We'll write the entry code later. __ b(&entry_label_); // We'll write the entry code later.
// If the code gets too big or corrupted, an internal exception will be // If the code gets too big or corrupted, an internal exception will be
......
...@@ -289,9 +289,9 @@ int NativeRegExpMacroAssembler::Execute( ...@@ -289,9 +289,9 @@ int NativeRegExpMacroAssembler::Execute(
Address regexp); Address regexp);
auto fn = GeneratedCode<RegexpMatcherSig>::FromCode(code); auto fn = GeneratedCode<RegexpMatcherSig>::FromCode(code);
int result = fn.CallIrregexp(input.ptr(), start_offset, input_start, int result =
input_end, output, output_size, stack_base, fn.Call(input.ptr(), start_offset, input_start, input_end, output,
call_origin, isolate, regexp.ptr()); output_size, stack_base, call_origin, isolate, regexp.ptr());
DCHECK(result >= RETRY); DCHECK(result >= RETRY);
if (result == EXCEPTION && !isolate->has_pending_exception()) { if (result == EXCEPTION && !isolate->has_pending_exception()) {
......
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