Skip to content

Commit 6b5cb45

Browse files
authored
Merge pull request #2 from caizixian/jdk-20+16-mmtk-fastpath
Basic non-zero build support on riscv
2 parents bcbf324 + 7ba5130 commit 6b5cb45

9 files changed

+253
-16
lines changed

mmtk/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ lto = true
1717
[package.metadata.openjdk]
1818
# Our CI matches the following line and extract mmtk/openjdk. If this line is updated, please check ci yaml files and make sure it works.
1919
openjdk_repo = "https://github.com/caizixian/jdk-mmtk.git"
20-
openjdk_version = "d4ae3c7ebda257f018b3b538b7ecd1ced7a91bc1"
20+
openjdk_version = "b369f54e36e79d5cc3e67424209be3bbae60d644"
2121

2222
[dependencies]
2323
libc = "0.2"

openjdk/CompileThirdPartyHeap.gmk

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,31 @@ else
5555
CARGO_PROFILE = debug
5656
endif
5757

58+
CARGO_EXECUTABLE = cargo
59+
CARGO_TARGET = .
60+
CARGO_TARGET_FLAG =
61+
62+
ifeq ($(COMPILE_TYPE), cross)
63+
ifneq ($(CREATING_BUILDJDK), true)
64+
CARGO_EXECUTABLE = cross
65+
CARGO_TARGET = riscv64gc-unknown-linux-gnu
66+
CARGO_TARGET_FLAG = --target $(CARGO_TARGET)
67+
endif
68+
endif
69+
5870
$(LIB_MMTK): FORCE
5971
if [[ "$(OPENJDK_VERSION)" != "$(OPENJDK_LOCAL_VERSION)" ]]; then \
6072
echo -e $(YELLOW)WARNING: Local OpenJDK version does not match version specified in mmtk/Cargo.toml$(NC); \
6173
echo -e $(YELLOW)Local OpenJDK version $(OPENJDK_LOCAL_VERSION)$(NC); \
6274
echo -e $(YELLOW)mmtk/Cargo.toml OpenJDK version $(OPENJDK_VERSION)$(NC); \
6375
fi
64-
echo "cd $(MMTK_RUST_ROOT) && cargo build $(CARGO_PROFILE_FLAG) $(GC_FEATURES)"
65-
cd $(MMTK_RUST_ROOT) && cargo build $(CARGO_PROFILE_FLAG) $(GC_FEATURES)
66-
mkdir -p $(JVM_LIB_OUTPUTDIR) && cp $(MMTK_RUST_ROOT)/target/$(CARGO_PROFILE)/libmmtk_openjdk.so $(LIB_MMTK)
76+
if [[ "$(OPENJDK_TARGET_CPU)" != "riscv64" ]] && [[ $(CARGO_EXECUTABLE) == "cross" ]]; then \
77+
echo -e "Only cross compiling to riscv64 is supported"; \
78+
exit 1; \
79+
fi
80+
echo "cd $(MMTK_RUST_ROOT) && $(CARGO_EXECUTABLE) build $(CARGO_TARGET_FLAG) $(CARGO_PROFILE_FLAG) $(GC_FEATURES)"
81+
cd $(MMTK_RUST_ROOT) && $(CARGO_EXECUTABLE) build $(CARGO_TARGET_FLAG) $(CARGO_PROFILE_FLAG) $(GC_FEATURES)
82+
mkdir -p $(JVM_LIB_OUTPUTDIR) && cp $(MMTK_RUST_ROOT)/target/$(CARGO_TARGET)/$(CARGO_PROFILE)/libmmtk_openjdk.so $(LIB_MMTK)
6783

6884
JVM_LIBS += -L$(JVM_LIB_OUTPUTDIR) -lmmtk_openjdk
6985
JVM_LDFLAGS += '-Wl,-rpath,$$ORIGIN'
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*
23+
*/
24+
#include "precompiled.hpp"
25+
#include "asm/macroAssembler.inline.hpp"
26+
#include "interpreter/interp_masm.hpp"
27+
#include "mmtkBarrierSet.hpp"
28+
#include "mmtkBarrierSetAssembler_riscv.hpp"
29+
#include "mmtkBarrierSetC1.hpp"
30+
#include "mmtkMutator.hpp"
31+
#include "runtime/sharedRuntime.hpp"
32+
#include "utilities/macros.hpp"
33+
#include "c1/c1_LIRAssembler.hpp"
34+
#include "c1/c1_MacroAssembler.hpp"
35+
36+
#define __ masm->
37+
38+
void MMTkBarrierSetAssembler::eden_allocate(MacroAssembler* masm, Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register tmp1, Register tmp2, Label& slow_case, bool is_far) {
39+
// XXX tmp1 seems to be -1
40+
assert_different_registers(obj, tmp2);
41+
assert_different_registers(obj, var_size_in_bytes);
42+
assert(tmp2->is_valid(), "need temp reg");
43+
44+
if (!MMTK_ENABLE_ALLOCATION_FASTPATH) {
45+
__ j(slow_case);
46+
} else {
47+
// printf("generating mmtk allocation fast path\n");
48+
// MMTk size check. If the alloc size is larger than the allowed max size for non los,
49+
// we jump to slow path and allodate with LOS in slowpath.
50+
// Note that OpenJDK has a slow path check. Search for layout_helper_needs_slow_path and FastAllocateSizeLimit.
51+
// I tried to set FastAllocateSizeLimit in MMTkHeap::initialize(). But there are still large objects allocated into the
52+
// default space.
53+
assert(MMTkMutatorContext::max_non_los_default_alloc_bytes != 0, "max_non_los_default_alloc_bytes hasn't been initialized");
54+
size_t max_non_los_bytes = MMTkMutatorContext::max_non_los_default_alloc_bytes;
55+
size_t extra_header = 0;
56+
// fastpath, we only use default allocator
57+
Allocator allocator = AllocatorDefault;
58+
// We need to figure out which allocator we are using by querying MMTk.
59+
AllocatorSelector selector = get_allocator_mapping(allocator);
60+
61+
// XXX riscv: disallow markcompact and global alloc bit for now
62+
assert(selector.tag != TAG_MARK_COMPACT, "mark compact not supported for now");
63+
64+
if (var_size_in_bytes == noreg) {
65+
// constant alloc size. If it is larger than max_non_los_bytes, we directly go to slowpath.
66+
if ((size_t)con_size_in_bytes > max_non_los_bytes - extra_header) {
67+
__ j(slow_case);
68+
return;
69+
}
70+
} else {
71+
// var alloc size. We compare with max_non_los_bytes and conditionally jump to slowpath.
72+
// printf("max_non_los_bytes %lu\n",max_non_los_bytes);
73+
__ li(t0, max_non_los_bytes - extra_header);
74+
__ bgeu(var_size_in_bytes, t0, slow_case, is_far);
75+
}
76+
77+
if (selector.tag == TAG_MALLOC || selector.tag == TAG_LARGE_OBJECT) {
78+
__ j(slow_case);
79+
return;
80+
}
81+
82+
// Calculate offsets of TLAB top and end
83+
Address cursor, limit;
84+
MMTkAllocatorOffsets alloc_offsets = get_tlab_top_and_end_offsets(selector);
85+
86+
cursor = Address(xthread, alloc_offsets.tlab_top_offset);
87+
limit = Address(xthread, alloc_offsets.tlab_end_offset);
88+
89+
// XXX disassembly
90+
// 0x7fffe85597e0: ld a0,688(s7)
91+
// 0x7fffe85597e4: add a1,a0,a3
92+
// 0x7fffe85597e8: bltu a1,a0,0x7fffe8559878
93+
// 0x7fffe85597ec: ld t0,696(s7)
94+
// 0x7fffe85597f0: bltu t0,a1,0x7fffe8559878
95+
// 0x7fffe85597f4: sd a1,688(s7)
96+
97+
// obj = load lab.cursor
98+
__ ld(obj, cursor);
99+
// end = obj + size
100+
Register end = tmp2;
101+
if (var_size_in_bytes == noreg) {
102+
__ la(end, Address(obj, con_size_in_bytes));
103+
} else {
104+
__ add(end, obj, var_size_in_bytes);
105+
}
106+
// slowpath if end < obj
107+
__ bltu(end, obj, slow_case, is_far);
108+
// slowpath if end > lab.limit
109+
__ ld(t0, limit);
110+
// XXX debug use, force slow path
111+
// __ bgtu(end, zr, slow_case, is_far);
112+
__ bgtu(end, t0, slow_case, is_far);
113+
// lab.cursor = end
114+
__ sd(end, cursor);
115+
116+
// recover var_size_in_bytes if necessary
117+
if (var_size_in_bytes == end) {
118+
__ sub(var_size_in_bytes, var_size_in_bytes, obj);
119+
}
120+
// if the above is removed, and the register holding the object size is
121+
// clobbered, operations that rely on the size, such as array copy will
122+
// crash
123+
124+
// XXX debug use, force segfault to disassemble in gdb
125+
// __ ld(t0, zr);
126+
127+
// XXX debug use, force double allocation
128+
// __ j(slow_case);
129+
130+
#ifdef MMTK_ENABLE_GLOBAL_ALLOC_BIT
131+
assert(false, "global alloc bit not supported");
132+
#endif
133+
}
134+
}
135+
136+
#undef __
137+
138+
#define __ sasm->
139+
140+
void MMTkBarrierSetAssembler::generate_c1_write_barrier_runtime_stub(StubAssembler* sasm) const {
141+
// assert(false, "Not implemented");
142+
}
143+
144+
#undef __
145+
146+
#define __ ce->masm()->
147+
148+
void MMTkBarrierSetAssembler::generate_c1_write_barrier_stub_call(LIR_Assembler* ce, MMTkC1BarrierStub* stub) {
149+
// assert(false, "Not implemented");
150+
}
151+
152+
#undef __
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#ifndef MMTK_OPENJDK_MMTK_BARRIER_SET_ASSEMBLER_RISCV_HPP
2+
#define MMTK_OPENJDK_MMTK_BARRIER_SET_ASSEMBLER_RISCV_HPP
3+
4+
#include "asm/macroAssembler.hpp"
5+
#include "gc/shared/barrierSetAssembler.hpp"
6+
7+
class MMTkBarrierSetC1;
8+
class MMTkC1BarrierStub;
9+
class LIR_Assembler;
10+
class StubAssembler;
11+
12+
class MMTkBarrierSetAssembler: public BarrierSetAssembler {
13+
friend class MMTkBarrierSetC1;
14+
15+
protected:
16+
/// Full pre-barrier
17+
virtual void object_reference_write_pre(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const {}
18+
/// Full post-barrier
19+
virtual void object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const {}
20+
21+
/// Barrier elision test
22+
virtual bool can_remove_barrier(DecoratorSet decorators, Register val, bool skip_const_null) const {
23+
bool in_heap = (decorators & IN_HEAP) != 0;
24+
bool as_normal = (decorators & AS_NORMAL) != 0;
25+
assert((decorators & IS_DEST_UNINITIALIZED) == 0, "unsupported");
26+
return !in_heap || (skip_const_null && val == noreg);
27+
}
28+
29+
/// Generate C1 write barrier slow-call assembly code
30+
virtual void generate_c1_write_barrier_runtime_stub(StubAssembler* sasm) const;
31+
32+
public:
33+
virtual void eden_allocate(MacroAssembler* masm,
34+
Register obj, // result: pointer to object after successful allocation
35+
Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
36+
int con_size_in_bytes, // object size in bytes if known at compile time
37+
Register tmp1, // temp register
38+
Register tmp2, // temp register
39+
Label& slow_case, // continuation point if fast allocation fails
40+
bool is_far = false
41+
) override;
42+
virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
43+
if (type == T_OBJECT || type == T_ARRAY) object_reference_write_pre(masm, decorators, dst, val, tmp1, tmp2);
44+
BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3);
45+
if (type == T_OBJECT || type == T_ARRAY) object_reference_write_post(masm, decorators, dst, val, tmp1, tmp2);
46+
}
47+
48+
/// Generate C1 write barrier slow-call stub
49+
static void generate_c1_write_barrier_stub_call(LIR_Assembler* ce, MMTkC1BarrierStub* stub);
50+
};
51+
#endif // MMTK_OPENJDK_MMTK_BARRIER_SET_ASSEMBLER_RISCV_HPP

openjdk/cpu/x86/mmtkBarrierSetAssembler_x86.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class MMTkBarrierSetAssembler: public BarrierSetAssembler {
3030
virtual void generate_c1_write_barrier_runtime_stub(StubAssembler* sasm) const;
3131

3232
public:
33-
virtual void eden_allocate(MacroAssembler* masm, Register thread, Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Label& slow_case);
33+
virtual void eden_allocate(MacroAssembler* masm, Register thread, Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Label& slow_case) override;
3434
virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Address dst, Register val, Register tmp1, Register tmp2, Register tmp3) {
3535
if (type == T_OBJECT || type == T_ARRAY) object_reference_write_pre(masm, decorators, dst, val, tmp1, tmp2);
3636
BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3);

openjdk/share/barriers/mmtkObjectBarrier.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ void MMTkObjectBarrierSetRuntime::object_reference_write_post(oop src, oop* slot
2121
#define __ masm->
2222

2323
void MMTkObjectBarrierSetAssembler::object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const {
24-
if (can_remove_barrier(decorators, val, /* skip_const_null */ true)) return;
24+
//if (can_remove_barrier(decorators, val, /* skip_const_null */ true)) return;
25+
/*
2526
#if MMTK_ENABLE_BARRIER_FASTPATH
2627
Label done;
2728
@@ -66,18 +67,21 @@ void MMTkObjectBarrierSetAssembler::object_reference_write_post(MacroAssembler*
6667
__ movptr(c_rarg2, val == noreg ? (int32_t) NULL_WORD : val);
6768
__ call_VM_leaf_base(FN_ADDR(MMTkBarrierSetRuntime::object_reference_write_post_call), 3);
6869
#endif
70+
*/
71+
assert(false, "Not implemented");
6972
}
7073

7174
void MMTkObjectBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register src, Register dst, Register count) {
72-
const bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
73-
if ((type == T_OBJECT || type == T_ARRAY) && !dest_uninitialized) {
74-
__ pusha();
75-
__ movptr(c_rarg0, src);
76-
__ movptr(c_rarg1, dst);
77-
__ movptr(c_rarg2, count);
78-
__ call_VM_leaf_base(FN_ADDR(MMTkBarrierSetRuntime::object_reference_array_copy_post_call), 3);
79-
__ popa();
80-
}
75+
// const bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
76+
// if ((type == T_OBJECT || type == T_ARRAY) && !dest_uninitialized) {
77+
// __ pusha();
78+
// __ movptr(c_rarg0, src);
79+
// __ movptr(c_rarg1, dst);
80+
// __ movptr(c_rarg2, count);
81+
// __ call_VM_leaf_base(FN_ADDR(MMTkBarrierSetRuntime::object_reference_array_copy_post_call), 3);
82+
// __ popa();
83+
// }
84+
assert(false, "Not implemented");
8185
}
8286

8387
#undef __

openjdk/share/barriers/mmtkObjectBarrier.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class MMTkObjectBarrierSetAssembler: public MMTkBarrierSetAssembler {
4141
protected:
4242
virtual void object_reference_write_post(MacroAssembler* masm, DecoratorSet decorators, Address dst, Register val, Register tmp1, Register tmp2) const override;
4343
public:
44-
virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register src, Register dst, Register count) override;
44+
virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type, Register src, Register dst, Register count);
4545
};
4646
#endif
4747

openjdk/share/mmtkRootsClosure.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,14 @@ class MMTkScanObjectClosure : public BasicOopIterateClosure {
140140
// }
141141
// };
142142

143+
class CodeBlobFixRelocationClosure: public CodeBlobClosure {
144+
public:
145+
inline virtual void do_code_blob(CodeBlob* cb) {
146+
nmethod* nm = cb->as_nmethod_or_null();
147+
if (nm != NULL) {
148+
nm->fix_oop_relocations();
149+
}
150+
}
151+
};
152+
143153
#endif // MMTK_OPENJDK_MMTK_ROOTS_CLOSURE_HPP

openjdk/share/mmtkUpcalls.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ static void mmtk_resume_mutators(void *tls) {
7676
#if COMPILER2_OR_JVMCI
7777
DerivedPointerTable::update_pointers();
7878
#endif
79+
{
80+
CodeBlobFixRelocationClosure cb_cl;
81+
CodeCache::blobs_do(&cb_cl);
82+
}
7983

8084
// Note: we don't have to hold gc_lock to increment the counter.
8185
// The increment has to be done before mutators can be resumed

0 commit comments

Comments
 (0)