Commit d25088e9 authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

Reland "[ia32,root] Add indirect calls and jumps through virtual register"

This is a reland of 65070355

Original change's description:
> [ia32,root] Add indirect calls and jumps through virtual register
>
> This adds a temporary mechanism for isolate-independent calls and
> jumps.  The problem was that - as ia32 doesn't have a scratch register
> - Call and Jump cannot call through a register. This CL adds a
> so-called virtual register (= a pointer-sized field) on IsolateData.
>
> The virtual register can be removed once pc-relative calls are
> implemented and all builtins have been embedded.
>
> Bug: v8:6666
> Change-Id: I1f9d8a25643fad0b3919dd813dbe219d20fcc6bc
> Reviewed-on: https://chromium-review.googlesource.com/c/1282991
> Commit-Queue: Jakob Gruber <jgruber@chromium.org>
> Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
> Reviewed-by: Igor Sheludko <ishell@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#56693}

TBR=sigurds@chromium.org

Bug: v8:6666
Change-Id: If463e68036673c7873d0d5e1a8a01ef31263cbfa
Reviewed-on: https://chromium-review.googlesource.com/c/1283052
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56700}
parent 952c0976
This diff is collapsed.
......@@ -1898,15 +1898,20 @@ void TurboAssembler::CallCFunction(Register function, int num_arguments) {
void TurboAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) {
if (FLAG_embedded_builtins) {
// TODO(jgruber): Pc-relative builtin-to-builtin calls.
if (root_array_available_ && options().isolate_independent_code) {
// TODO(jgruber): There's no scratch register on ia32. Any call that
// requires loading a code object from the builtins constant table must:
// 1) spill two scratch registers, 2) load the target into scratch1, 3)
// store the target into a virtual register on the isolate using scratch2,
// 4) restore both scratch registers, and finally 5) call through the
// virtual register. All affected call sites should vanish once all
// builtins are embedded on ia32.
UNREACHABLE();
if (root_array_available_ && ShouldGenerateIsolateIndependentCode() &&
Builtins::IsBuiltin(*code_object)) {
// Since we don't have a scratch register available we call through a
// so-called virtual register.
// TODO(v8:6666): Remove once pc-relative jumps are supported on ia32.
Assembler::AllowExplicitEbxAccessScope read_only_access(this);
Operand virtual_call_target_register(
kRootRegister,
IsolateData::kVirtualCallTargetRegisterOffset - kRootRegisterBias);
Move(virtual_call_target_register, Immediate(code_object));
add(virtual_call_target_register,
Immediate(Code::kHeaderSize - kHeapObjectTag));
call(virtual_call_target_register);
return;
} else if (options().inline_offheap_trampolines) {
int builtin_index = Builtins::kNoBuiltinId;
if (isolate()->builtins()->IsBuiltinHandle(code_object, &builtin_index) &&
......@@ -1928,15 +1933,20 @@ void TurboAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) {
void TurboAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) {
if (FLAG_embedded_builtins) {
// TODO(jgruber): Pc-relative builtin-to-builtin calls.
if (root_array_available_ && options().isolate_independent_code) {
// TODO(jgruber): There's no scratch register on ia32. Any call that
// requires loading a code object from the builtins constant table must:
// 1) spill two scratch registers, 2) load the target into scratch1, 3)
// store the target into a virtual register on the isolate using scratch2,
// 4) restore both scratch registers, and finally 5) call through the
// virtual register. All affected call sites should vanish once all
// builtins are embedded on ia32.
UNREACHABLE();
if (root_array_available_ && ShouldGenerateIsolateIndependentCode() &&
Builtins::IsBuiltin(*code_object)) {
// Since we don't have a scratch register available we call through a
// so-called virtual register.
// TODO(v8:6666): Remove once pc-relative jumps are supported on ia32.
Assembler::AllowExplicitEbxAccessScope read_only_access(this);
Operand virtual_call_target_register(
kRootRegister,
IsolateData::kVirtualCallTargetRegisterOffset - kRootRegisterBias);
Move(virtual_call_target_register, Immediate(code_object));
add(virtual_call_target_register,
Immediate(Code::kHeaderSize - kHeapObjectTag));
jmp(virtual_call_target_register);
return;
} else if (options().inline_offheap_trampolines) {
int builtin_index = Builtins::kNoBuiltinId;
if (isolate()->builtins()->IsBuiltinHandle(code_object, &builtin_index) &&
......
......@@ -39,7 +39,8 @@ class IsolateData final {
V(kBuiltinsTableEndOffset, 0) \
/* magic_number_ */ \
V(kMagicNumberOffset, kIntptrSize) \
V(kMagicNumberEndOffset, 0) \
/* virtual_call_target_register_ */ \
V(kVirtualCallTargetRegisterOffset, kPointerSize) \
/* Total size. */ \
V(kSize, 0)
......@@ -79,6 +80,10 @@ class IsolateData final {
// TODO(v8:6666): Remove once the root register is fully supported on ia32.
const intptr_t magic_number_ = kRootRegisterSentinel;
// For isolate-independent calls on ia32.
// TODO(v8:6666): Remove once pc-relative jumps are supported on ia32.
void* virtual_call_target_register_ = nullptr;
V8_INLINE static void AssertPredictableLayout();
friend class Isolate;
......
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