File: SharedICHelpers-mips-shared.h

package info (click to toggle)
thunderbird 1:60.8.0-1~deb9u1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 2,339,208 kB
  • sloc: cpp: 5,456,704; ansic: 2,360,384; python: 596,095; asm: 340,963; java: 326,291; xml: 258,664; sh: 84,366; makefile: 23,702; perl: 17,317; objc: 3,768; yacc: 1,766; ada: 1,681; lex: 1,364; pascal: 1,264; cs: 879; exp: 527; php: 436; lisp: 258; ruby: 153; awk: 152; sed: 53; csh: 27
file content (130 lines) | stat: -rw-r--r-- 4,664 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef jit_mips_shared_SharedICHelpers_mips_shared_h
#define jit_mips_shared_SharedICHelpers_mips_shared_h

#include "jit/BaselineFrame.h"
#include "jit/BaselineIC.h"
#include "jit/MacroAssembler.h"
#include "jit/SharedICRegisters.h"

namespace js {
namespace jit {

// Distance from sp to the top Value inside an IC stub (no return address on
// the stack on MIPS).
static const size_t ICStackValueOffset = 0;

struct BaselineStubFrame {
  uintptr_t savedFrame;
  uintptr_t savedStub;
  uintptr_t returnAddress;
  uintptr_t descriptor;
};

// Size of values pushed by EmitBaselineEnterStubFrame.
static const uint32_t STUB_FRAME_SIZE = sizeof(BaselineStubFrame);
static const uint32_t STUB_FRAME_SAVED_STUB_OFFSET =
    offsetof(BaselineStubFrame, savedStub);

inline void EmitRestoreTailCallReg(MacroAssembler& masm) {
  // No-op on MIPS because ra register is always holding the return address.
}

inline void EmitRepushTailCallReg(MacroAssembler& masm) {
  // No-op on MIPS because ra register is always holding the return address.
}

inline void EmitCallIC(CodeOffset* patchOffset, MacroAssembler& masm) {
  // Move ICEntry offset into ICStubReg.
  CodeOffset offset = masm.movWithPatch(ImmWord(-1), ICStubReg);
  *patchOffset = offset;

  // Load stub pointer into ICStubReg.
  masm.loadPtr(Address(ICStubReg, ICEntry::offsetOfFirstStub()), ICStubReg);

  // Load stubcode pointer from BaselineStubEntry.
  // R2 won't be active when we call ICs, so we can use it as scratch.
  masm.loadPtr(Address(ICStubReg, ICStub::offsetOfStubCode()), R2.scratchReg());

  // Call the stubcode via a direct jump-and-link
  masm.call(R2.scratchReg());
}

inline void EmitEnterTypeMonitorIC(
    MacroAssembler& masm,
    size_t monitorStubOffset = ICMonitoredStub::offsetOfFirstMonitorStub()) {
  // This is expected to be called from within an IC, when ICStubReg
  // is properly initialized to point to the stub.
  masm.loadPtr(Address(ICStubReg, (uint32_t)monitorStubOffset), ICStubReg);

  // Load stubcode pointer from BaselineStubEntry.
  // R2 won't be active when we call ICs, so we can use it.
  masm.loadPtr(Address(ICStubReg, ICStub::offsetOfStubCode()), R2.scratchReg());

  // Jump to the stubcode.
  masm.branch(R2.scratchReg());
}

inline void EmitReturnFromIC(MacroAssembler& masm) { masm.branch(ra); }

inline void EmitChangeICReturnAddress(MacroAssembler& masm, Register reg) {
  masm.movePtr(reg, ra);
}

inline void EmitBaselineLeaveStubFrame(MacroAssembler& masm,
                                       bool calledIntoIon = false) {
  // Ion frames do not save and restore the frame pointer. If we called
  // into Ion, we have to restore the stack pointer from the frame descriptor.
  // If we performed a VM call, the descriptor has been popped already so
  // in that case we use the frame pointer.
  if (calledIntoIon) {
    masm.pop(ScratchRegister);
    masm.rshiftPtr(Imm32(FRAMESIZE_SHIFT), ScratchRegister);
    masm.addPtr(ScratchRegister, BaselineStackReg);
  } else {
    masm.movePtr(BaselineFrameReg, BaselineStackReg);
  }

  masm.loadPtr(Address(StackPointer, offsetof(BaselineStubFrame, savedFrame)),
               BaselineFrameReg);
  masm.loadPtr(Address(StackPointer, offsetof(BaselineStubFrame, savedStub)),
               ICStubReg);

  // Load the return address.
  masm.loadPtr(
      Address(StackPointer, offsetof(BaselineStubFrame, returnAddress)),
      ICTailCallReg);

  // Discard the frame descriptor.
  masm.loadPtr(Address(StackPointer, offsetof(BaselineStubFrame, descriptor)),
               ScratchRegister);
  masm.addPtr(Imm32(STUB_FRAME_SIZE), StackPointer);
}

template <typename AddrType>
inline void EmitPreBarrier(MacroAssembler& masm, const AddrType& addr,
                           MIRType type) {
  // On MIPS, $ra is clobbered by guardedCallPreBarrier. Save it first.
  masm.push(ra);
  masm.guardedCallPreBarrier(addr, type);
  masm.pop(ra);
}

inline void EmitStubGuardFailure(MacroAssembler& masm) {
  // Load next stub into ICStubReg
  masm.loadPtr(Address(ICStubReg, ICStub::offsetOfNext()), ICStubReg);

  // Return address is already loaded, just jump to the next stubcode.
  MOZ_ASSERT(ICTailCallReg == ra);
  masm.jump(Address(ICStubReg, ICStub::offsetOfStubCode()));
}

}  // namespace jit
}  // namespace js

#endif /* jit_mips_shared_SharedICHelpers_mips_shared_h */