summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2019-10-23 15:01:12 +0200
committerMichaël Zasso <targos@protonmail.com>2019-11-08 15:53:20 +0100
commita9bed0b72b088b5ae8eef625a41b76225686c3f7 (patch)
treef8ea194ed1f9896c36c8c1805041b7149ec075b4 /deps/v8/src/compiler
parentd9fab1fdb76ae3a69b5812a7f2190cf3e58f6d75 (diff)
downloadandroid-node-v8-a9bed0b72b088b5ae8eef625a41b76225686c3f7.tar.gz
android-node-v8-a9bed0b72b088b5ae8eef625a41b76225686c3f7.tar.bz2
android-node-v8-a9bed0b72b088b5ae8eef625a41b76225686c3f7.zip
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: https://github.com/v8/v8/commit/07ee86a5a28b7f9526748ca8f765c1b704f93c0c PR-URL: https://github.com/nodejs/node/pull/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>
Diffstat (limited to 'deps/v8/src/compiler')
-rw-r--r--deps/v8/src/compiler/backend/instruction-selector.cc13
-rw-r--r--deps/v8/src/compiler/backend/instruction.h3
-rw-r--r--deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc15
-rw-r--r--deps/v8/src/compiler/code-assembler.cc7
-rw-r--r--deps/v8/src/compiler/code-assembler.h16
-rw-r--r--deps/v8/src/compiler/linkage.h9
-rw-r--r--deps/v8/src/compiler/raw-machine-assembler.cc12
-rw-r--r--deps/v8/src/compiler/raw-machine-assembler.h16
8 files changed, 82 insertions, 9 deletions
diff --git a/deps/v8/src/compiler/backend/instruction-selector.cc b/deps/v8/src/compiler/backend/instruction-selector.cc
index 22d81c0c55..e165c6c6a9 100644
--- a/deps/v8/src/compiler/backend/instruction-selector.cc
+++ b/deps/v8/src/compiler/backend/instruction-selector.cc
@@ -2810,10 +2810,17 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
// Select the appropriate opcode based on the call type.
InstructionCode opcode = kArchNop;
switch (call_descriptor->kind()) {
- case CallDescriptor::kCallAddress:
- opcode = kArchCallCFunction | MiscField::encode(static_cast<int>(
- call_descriptor->ParameterCount()));
+ case CallDescriptor::kCallAddress: {
+ int misc_field = static_cast<int>(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;
+ }
case CallDescriptor::kCallCodeObject:
opcode = kArchCallCodeObject | MiscField::encode(flags);
break;
diff --git a/deps/v8/src/compiler/backend/instruction.h b/deps/v8/src/compiler/backend/instruction.h
index 321f069531..462b0daf6b 100644
--- a/deps/v8/src/compiler/backend/instruction.h
+++ b/deps/v8/src/compiler/backend/instruction.h
@@ -807,7 +807,8 @@ class V8_EXPORT_PRIVATE Instruction final {
size_t output_count, InstructionOperand* outputs,
size_t input_count, InstructionOperand* inputs,
size_t temp_count, InstructionOperand* temps) {
- DCHECK_LE(0, opcode);
+ // TODO(9872)
+ // DCHECK_LE(0, opcode);
DCHECK(output_count == 0 || outputs != nullptr);
DCHECK(input_count == 0 || inputs != nullptr);
DCHECK(temp_count == 0 || temps != nullptr);
diff --git a/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc b/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc
index dde1804adb..964f888816 100644
--- a/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc
+++ b/deps/v8/src/compiler/backend/ppc/code-generator-ppc.cc
@@ -1019,13 +1019,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
#endif
break;
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;
bool isWasmCapiFunction =
linkage()->GetIncomingDescriptor()->IsWasmCapiFunction();
#if defined(_AIX)
// 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;
#else
constexpr int offset = 9 * kInstrSize;
@@ -1041,10 +1048,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
if (instr->InputAt(0)->IsImmediate()) {
ExternalReference ref = i.InputExternalReference(0);
- __ CallCFunction(ref, num_parameters);
+ __ CallCFunction(ref, num_parameters, has_function_descriptor);
} else {
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
// the strictly-correct PC, which is the return address at this spot. The
diff --git a/deps/v8/src/compiler/code-assembler.cc b/deps/v8/src/compiler/code-assembler.cc
index 5b89e1b663..c618daf357 100644
--- a/deps/v8/src/compiler/code-assembler.cc
+++ b/deps/v8/src/compiler/code-assembler.cc
@@ -1439,6 +1439,13 @@ Node* CodeAssembler::CallCFunction(
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* function, MachineType return_type, SaveFPRegsMode mode,
std::initializer_list<CodeAssembler::CFunctionArg> args) {
diff --git a/deps/v8/src/compiler/code-assembler.h b/deps/v8/src/compiler/code-assembler.h
index 036b00b14d..8d5b860285 100644
--- a/deps/v8/src/compiler/code-assembler.h
+++ b/deps/v8/src/compiler/code-assembler.h
@@ -1103,6 +1103,18 @@ class V8_EXPORT_PRIVATE CodeAssembler {
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.
template <class... CArgs>
Node* CallCFunctionWithCallerSavedRegisters(Node* function,
@@ -1151,6 +1163,10 @@ class V8_EXPORT_PRIVATE CodeAssembler {
Node* CallCFunction(Node* function, MachineType return_type,
std::initializer_list<CFunctionArg> args);
+ Node* CallCFunctionWithoutFunctionDescriptor(
+ Node* function, MachineType return_type,
+ std::initializer_list<CFunctionArg> args);
+
Node* CallCFunctionWithCallerSavedRegisters(
Node* function, MachineType return_type, SaveFPRegsMode mode,
std::initializer_list<CFunctionArg> args);
diff --git a/deps/v8/src/compiler/linkage.h b/deps/v8/src/compiler/linkage.h
index 69e7fbfa42..5458d1eb6f 100644
--- a/deps/v8/src/compiler/linkage.h
+++ b/deps/v8/src/compiler/linkage.h
@@ -352,9 +352,18 @@ class V8_EXPORT_PRIVATE CallDescriptor final
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:
friend class Linkage;
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 MachineType target_type_;
diff --git a/deps/v8/src/compiler/raw-machine-assembler.cc b/deps/v8/src/compiler/raw-machine-assembler.cc
index c709729081..7031437cc2 100644
--- a/deps/v8/src/compiler/raw-machine-assembler.cc
+++ b/deps/v8/src/compiler/raw-machine-assembler.cc
@@ -705,7 +705,8 @@ namespace {
Node* CallCFunctionImpl(
RawMachineAssembler* rasm, Node* function, MachineType return_type,
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;
MachineSignature::Builder builder(rasm->zone(), 1, args.size());
@@ -719,6 +720,8 @@ Node* CallCFunctionImpl(
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);
nodes[0] = function;
std::transform(
@@ -739,6 +742,13 @@ Node* RawMachineAssembler::CallCFunction(
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* function, MachineType return_type, SaveFPRegsMode mode,
std::initializer_list<RawMachineAssembler::CFunctionArg> args) {
diff --git a/deps/v8/src/compiler/raw-machine-assembler.h b/deps/v8/src/compiler/raw-machine-assembler.h
index cbbb719d54..c0bfd84a61 100644
--- a/deps/v8/src/compiler/raw-machine-assembler.h
+++ b/deps/v8/src/compiler/raw-machine-assembler.h
@@ -983,6 +983,22 @@ class V8_EXPORT_PRIVATE RawMachineAssembler {
Node* CallCFunction(Node* function, MachineType return_type,
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.
template <class... CArgs>
Node* CallCFunctionWithCallerSavedRegisters(Node* function,