Commit 42591305 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[ia32,root] Temporarily allow calls through slot

This is necessary for the arguments adaptor, as there are only
5 gp registers available and a call to the arguments adaptor
trampoline that does not have the trampoline address as a immediate
needs 6 (4 arguments + esi as context + register to call through).

Bug: v8:6666
Change-Id: Ie96cf0352c323e07e0daf369953df8f4ee9acb81
Reviewed-on: https://chromium-review.googlesource.com/c/1283050
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56767}
parent 5bc6d241
......@@ -676,10 +676,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
switch (arch_opcode) {
case kArchCallCodeObject: {
MoveOperandIfAliasedWithPoisonRegister(instr, this);
if (HasImmediateInput(instr, 0)) {
InstructionOperand* op = instr->InputAt(0);
if (op->IsImmediate()) {
Handle<Code> code = i.InputCode(0);
__ Call(code, RelocInfo::CODE_TARGET);
} else {
} else if (op->IsRegister()) {
Register reg = i.InputRegister(0);
DCHECK_IMPLIES(
HasCallDescriptorFlag(instr, CallDescriptor::kFixedTargetRegister),
......@@ -690,6 +691,25 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
} else {
__ call(reg);
}
} else {
CHECK(tasm()->root_array_available());
// This is used to allow calls to the arguments adaptor trampoline from
// code that only has 5 gp registers available and cannot call through
// an immediate. This happens when the arguments adaptor trampoline is
// not an embedded builtin.
// TODO(v8:6666): Remove once only embedded builtins are supported.
__ push(eax);
frame_access_state()->IncreaseSPDelta(1);
TurboAssembler::AllowExplicitEbxAccessScope read_only_access(tasm());
Operand virtual_call_target_register(
kRootRegister,
IsolateData::kVirtualCallTargetRegisterOffset - kRootRegisterBias);
__ mov(eax, i.InputOperand(0));
__ add(eax, Immediate(Code::kHeaderSize - kHeapObjectTag));
__ mov(virtual_call_target_register, eax);
__ pop(eax);
frame_access_state()->IncreaseSPDelta(-1);
__ call(virtual_call_target_register);
}
RecordCallPosition(instr);
frame_access_state()->ClearSPDelta();
......
......@@ -886,6 +886,7 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
bool call_code_immediate = (flags & kCallCodeImmediate) != 0;
bool call_address_immediate = (flags & kCallAddressImmediate) != 0;
bool call_use_fixed_target_reg = (flags & kCallFixedTargetRegister) != 0;
bool call_through_slot = (flags & kAllowCallThroughSlot) != 0;
switch (buffer->descriptor->kind()) {
case CallDescriptor::kCallCodeObject:
// TODO(jgruber, v8:7449): The below is a hack to support tail-calls from
......@@ -899,7 +900,8 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
: call_use_fixed_target_reg
? g.UseFixed(callee, kJavaScriptCallCodeStartRegister)
: is_tail_call ? g.UseUniqueRegister(callee)
: g.UseRegister(callee));
: call_through_slot ? g.UseUniqueSlot(callee)
: g.UseRegister(callee));
break;
case CallDescriptor::kCallAddress:
buffer->instruction_args.push_back(
......@@ -2577,6 +2579,7 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
}
CallBuffer buffer(zone(), call_descriptor, frame_state_descriptor);
CallDescriptor::Flags flags = call_descriptor->flags();
// Compute InstructionOperands for inputs and outputs.
// TODO(turbofan): on some architectures it's probably better to use
......@@ -2584,12 +2587,21 @@ void InstructionSelector::VisitCall(Node* node, BasicBlock* handler) {
// Improve constant pool and the heuristics in the register allocator
// for where to emit constants.
CallBufferFlags call_buffer_flags(kCallCodeImmediate | kCallAddressImmediate);
if (flags & CallDescriptor::kAllowCallThroughSlot) {
// TODO(v8:6666): Remove kAllowCallThroughSlot and use a pc-relative call
// instead once builtins are embedded in every build configuration.
DCHECK(FLAG_embedded_builtins);
call_buffer_flags |= kAllowCallThroughSlot;
#ifndef V8_TARGET_ARCH_32_BIT
// kAllowCallThroughSlot is only supported on ia32.
UNREACHABLE();
#endif
}
InitializeCallBuffer(node, &buffer, call_buffer_flags, false);
EmitPrepareArguments(&(buffer.pushed_nodes), call_descriptor, node);
// Pass label of exception handler block.
CallDescriptor::Flags flags = call_descriptor->flags();
if (handler) {
DCHECK_EQ(IrOpcode::kIfException, handler->front()->opcode());
flags |= CallDescriptor::kHasExceptionHandler;
......@@ -2657,6 +2669,7 @@ void InstructionSelector::VisitTailCall(Node* node) {
if (callee->flags() & CallDescriptor::kFixedTargetRegister) {
flags |= kCallFixedTargetRegister;
}
DCHECK_EQ(callee->flags() & CallDescriptor::kAllowCallThroughSlot, 0);
InitializeCallBuffer(node, &buffer, flags, true, stack_param_delta);
// Select the appropriate opcode based on the call type.
......
......@@ -545,6 +545,7 @@ class V8_EXPORT_PRIVATE InstructionSelector final {
kCallAddressImmediate = 1u << 1,
kCallTail = 1u << 2,
kCallFixedTargetRegister = 1u << 3,
kAllowCallThroughSlot = 1u << 4
};
typedef base::Flags<CallBufferFlag> CallBufferFlags;
......
......@@ -191,7 +191,8 @@ class V8_EXPORT_PRIVATE CallDescriptor final
kRetpoline = 1u << 6,
// Use the kJavaScriptCallCodeStartRegister (fixed) register for the
// indirect target address when calling.
kFixedTargetRegister = 1u << 7
kFixedTargetRegister = 1u << 7,
kAllowCallThroughSlot = 1u << 8
};
typedef base::Flags<Flag> Flags;
......
......@@ -4626,9 +4626,16 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
args[pos++] = undefined_node;
}
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
#ifdef V8_TARGET_ARCH_IA32
// TODO(v8:6666): Remove kAllowCallThroughSlot and use a pc-relative
// call instead once builtins are embedded in every build configuration.
flags = FLAG_embedded_builtins ? CallDescriptor::kAllowCallThroughSlot
: CallDescriptor::kNoFlags;
#endif
auto call_descriptor = Linkage::GetStubCallDescriptor(
mcgraph()->zone(), ArgumentsAdaptorDescriptor{}, 1 + wasm_count,
CallDescriptor::kNoFlags, Operator::kNoProperties);
flags, Operator::kNoProperties);
// Convert wasm numbers to JS values.
pos = AddArgumentNodes(args, pos, wasm_count, sig_);
......
......@@ -901,44 +901,4 @@
'wasm/asm-wasm-f64': [SKIP],
}], # arch == x64
##############################################################################
['arch == ia32 and embedded_builtins == True', {
# TODO(v8:6666): Fix arguments adaptor trampoline
'wasm/compiled-module-serialization': [SKIP],
'asm/embenchen/copy': [SKIP],
'wasm/embenchen/corrections': [SKIP],
'asm/embenchen/primes': [SKIP],
'asm/embenchen/corrections': [SKIP],
'wasm/embenchen/copy': [SKIP],
'asm/embenchen/fannkuch': [SKIP],
'asm/embenchen/memops': [SKIP],
'asm/embenchen/fasta': [SKIP],
'wasm/embenchen/fannkuch': [SKIP],
'asm/embenchen/zlib': [SKIP],
'wasm/embenchen/fasta': [SKIP],
'wasm/embenchen/primes': [SKIP],
'wasm/embenchen/box2d': [SKIP],
'asm/embenchen/box2d': [SKIP],
'wasm/embenchen/memops': [SKIP],
'wasm/embenchen/zlib': [SKIP],
'asm/embenchen/lua_binarytrees': [SKIP],
'wasm/embenchen/lua_binarytrees': [SKIP],
'asm/sqlite3/sqlite': [SKIP],
'asm/sqlite3/sqlite-safe-heap': [SKIP],
'asm/sqlite3/sqlite-pointer-masking': [SKIP],
'asm/poppler/poppler': [SKIP],
'regress/wasm/regress-808848': [SKIP],
'regress/wasm/regress-834624': [SKIP],
'regress/wasm/regress-843563': [SKIP],
'wasm/anyref': [SKIP],
'wasm/exceptions-shared': [SKIP],
'wasm/errors': [SKIP],
'wasm/ffi-error': [SKIP],
'wasm/gc-frame': [SKIP],
'wasm/import-function': [SKIP],
'wasm/ffi': [SKIP],
'wasm/test-wasm-module-builder': [SKIP],
'wasm/stackwalk': [SKIP],
}], # arch == ia32 and embedded_builtins == True
]
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