Source code

Revision control

Other Tools

1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
* vim: set ts=8 sts=2 et sw=2 tw=80:
3
*
4
* Copyright 2019 Mozilla Foundation
5
*
6
* Licensed under the Apache License, Version 2.0 (the "License");
7
* you may not use this file except in compliance with the License.
8
* You may obtain a copy of the License at
9
*
11
*
12
* Unless required by applicable law or agreed to in writing, software
13
* distributed under the License is distributed on an "AS IS" BASIS,
14
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
* See the License for the specific language governing permissions and
16
* limitations under the License.
17
*/
18
19
#include "wasm/WasmGC.h"
20
#include "wasm/WasmInstance.h"
21
#include "jit/MacroAssembler-inl.h"
22
23
namespace js {
24
namespace wasm {
25
26
bool GenerateStackmapEntriesForTrapExit(const ValTypeVector& args,
27
const MachineState& trapExitLayout,
28
const size_t trapExitLayoutNumWords,
29
ExitStubMapVector* extras) {
30
MOZ_ASSERT(extras->empty());
31
32
// If this doesn't hold, we can't distinguish saved and not-saved
33
// registers in the MachineState. See MachineState::MachineState().
34
MOZ_ASSERT(trapExitLayoutNumWords < 0x100);
35
36
if (!extras->appendN(false, trapExitLayoutNumWords)) {
37
return false;
38
}
39
40
for (ABIArgIter<const ValTypeVector> i(args); !i.done(); i++) {
41
MOZ_ASSERT(i.mirType() != MIRType::Pointer);
42
if (!i->argInRegister() || i.mirType() != MIRType::RefOrNull) {
43
continue;
44
}
45
46
size_t offsetFromTop =
47
reinterpret_cast<size_t>(trapExitLayout.address(i->gpr()));
48
49
// If this doesn't hold, the associated register wasn't saved by
50
// the trap exit stub. Better to crash now than much later, in
51
// some obscure place, and possibly with security consequences.
52
MOZ_RELEASE_ASSERT(offsetFromTop < trapExitLayoutNumWords);
53
54
// offsetFromTop is an offset in words down from the highest
55
// address in the exit stub save area. Switch it around to be an
56
// offset up from the bottom of the (integer register) save area.
57
size_t offsetFromBottom = trapExitLayoutNumWords - 1 - offsetFromTop;
58
59
(*extras)[offsetFromBottom] = true;
60
}
61
62
return true;
63
}
64
65
void EmitWasmPreBarrierGuard(MacroAssembler& masm, Register tls,
66
Register scratch, Register valueAddr,
67
Label* skipBarrier) {
68
// If no incremental GC has started, we don't need the barrier.
69
masm.loadPtr(
70
Address(tls, offsetof(TlsData, addressOfNeedsIncrementalBarrier)),
71
scratch);
72
masm.branchTest32(Assembler::Zero, Address(scratch, 0), Imm32(0x1),
73
skipBarrier);
74
75
// If the previous value is null, we don't need the barrier.
76
masm.loadPtr(Address(valueAddr, 0), scratch);
77
masm.branchTestPtr(Assembler::Zero, scratch, scratch, skipBarrier);
78
}
79
80
void EmitWasmPreBarrierCall(MacroAssembler& masm, Register tls,
81
Register scratch, Register valueAddr) {
82
MOZ_ASSERT(valueAddr == PreBarrierReg);
83
84
masm.loadPtr(Address(tls, offsetof(TlsData, instance)), scratch);
85
masm.loadPtr(Address(scratch, Instance::offsetOfPreBarrierCode()), scratch);
86
#if defined(DEBUG) && defined(JS_CODEGEN_ARM64)
87
// The prebarrier assumes that x28 == sp.
88
Label ok;
89
masm.Cmp(sp, vixl::Operand(x28));
90
masm.B(&ok, Assembler::Equal);
91
masm.breakpoint();
92
masm.bind(&ok);
93
#endif
94
masm.call(scratch);
95
}
96
97
void EmitWasmPostBarrierGuard(MacroAssembler& masm,
98
const Maybe<Register>& object,
99
Register otherScratch, Register setValue,
100
Label* skipBarrier) {
101
// If the pointer being stored is null, no barrier.
102
masm.branchTestPtr(Assembler::Zero, setValue, setValue, skipBarrier);
103
104
// If there is a containing object and it is in the nursery, no barrier.
105
if (object) {
106
masm.branchPtrInNurseryChunk(Assembler::Equal, *object, otherScratch,
107
skipBarrier);
108
}
109
110
// If the pointer being stored is to a tenured object, no barrier.
111
masm.branchPtrInNurseryChunk(Assembler::NotEqual, setValue, otherScratch,
112
skipBarrier);
113
}
114
115
} // namespace wasm
116
} // namespace js