Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/js/src/jit/x64/SharedICHelpers-x64-inl.h
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
 * vim: set ts=8 sts=4 et sw=4 tw=99:
3
 * This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef jit_x64_SharedICHelpers_x64_inl_h
8
#define jit_x64_SharedICHelpers_x64_inl_h
9
10
#include "jit/SharedICHelpers.h"
11
12
#include "jit/MacroAssembler-inl.h"
13
14
namespace js {
15
namespace jit {
16
17
inline void
18
EmitBaselineTailCallVM(TrampolinePtr target, MacroAssembler& masm, uint32_t argSize)
19
14
{
20
14
    ScratchRegisterScope scratch(masm);
21
14
22
14
    // We an assume during this that R0 and R1 have been pushed.
23
14
    masm.movq(BaselineFrameReg, scratch);
24
14
    masm.addq(Imm32(BaselineFrame::FramePointerOffset), scratch);
25
14
    masm.subq(BaselineStackReg, scratch);
26
14
27
14
    // Store frame size without VMFunction arguments for GC marking.
28
14
    masm.movq(scratch, rdx);
29
14
    masm.subq(Imm32(argSize), rdx);
30
14
    masm.store32(rdx, Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFrameSize()));
31
14
32
14
    // Push frame descriptor and perform the tail call.
33
14
    masm.makeFrameDescriptor(scratch, FrameType::BaselineJS, ExitFrameLayout::Size());
34
14
    masm.push(scratch);
35
14
    masm.push(ICTailCallReg);
36
14
    masm.jump(target);
37
14
}
38
39
inline void
40
EmitBaselineCreateStubFrameDescriptor(MacroAssembler& masm, Register reg, uint32_t headerSize)
41
7
{
42
7
    // Compute stub frame size. We have to add two pointers: the stub reg and previous
43
7
    // frame pointer pushed by EmitEnterStubFrame.
44
7
    masm.movq(BaselineFrameReg, reg);
45
7
    masm.addq(Imm32(sizeof(void*) * 2), reg);
46
7
    masm.subq(BaselineStackReg, reg);
47
7
48
7
    masm.makeFrameDescriptor(reg, FrameType::BaselineStub, headerSize);
49
7
}
50
51
inline void
52
EmitBaselineCallVM(TrampolinePtr target, MacroAssembler& masm)
53
5
{
54
5
    ScratchRegisterScope scratch(masm);
55
5
    EmitBaselineCreateStubFrameDescriptor(masm, scratch, ExitFrameLayout::Size());
56
5
    masm.push(scratch);
57
5
    masm.call(target);
58
5
}
59
60
// Size of values pushed by EmitBaselineEnterStubFrame.
61
static const uint32_t STUB_FRAME_SIZE = 4 * sizeof(void*);
62
static const uint32_t STUB_FRAME_SAVED_STUB_OFFSET = sizeof(void*);
63
64
inline void
65
EmitBaselineEnterStubFrame(MacroAssembler& masm, Register)
66
7
{
67
7
    ScratchRegisterScope scratch(masm);
68
7
69
7
    // Compute frame size. Because the return address is still on the stack,
70
7
    // this is:
71
7
    //
72
7
    //   BaselineFrameReg
73
7
    //   + BaselineFrame::FramePointerOffset
74
7
    //   - BaselineStackReg
75
7
    //   - sizeof(return address)
76
7
    //
77
7
    // The two constants cancel each other out, so we can just calculate
78
7
    // BaselineFrameReg - BaselineStackReg.
79
7
80
7
    static_assert(BaselineFrame::FramePointerOffset == sizeof(void*),
81
7
                  "FramePointerOffset must be the same as the return address size");
82
7
83
7
    masm.movq(BaselineFrameReg, scratch);
84
7
    masm.subq(BaselineStackReg, scratch);
85
7
86
7
    masm.store32(scratch, Address(BaselineFrameReg, BaselineFrame::reverseOffsetOfFrameSize()));
87
7
88
7
    // Note: when making changes here,  don't forget to update STUB_FRAME_SIZE
89
7
    // if needed.
90
7
91
7
    // Push the return address that's currently on top of the stack.
92
7
    masm.Push(Operand(BaselineStackReg, 0));
93
7
94
7
    // Replace the original return address with the frame descriptor.
95
7
    masm.makeFrameDescriptor(scratch, FrameType::BaselineJS, BaselineStubFrameLayout::Size());
96
7
    masm.storePtr(scratch, Address(BaselineStackReg, sizeof(uintptr_t)));
97
7
98
7
    // Save old frame pointer, stack pointer and stub reg.
99
7
    masm.Push(ICStubReg);
100
7
    masm.Push(BaselineFrameReg);
101
7
    masm.mov(BaselineStackReg, BaselineFrameReg);
102
7
}
103
104
} // namespace jit
105
} // namespace js
106
107
#endif /* jit_x64_SharedICHelpers_x64_inl_h */