< prev index next > src/hotspot/cpu/riscv/c1_MacroAssembler_riscv.cpp
Print this page
#include "c1/c1_LIR.hpp"
#include "c1/c1_MacroAssembler.hpp"
#include "c1/c1_Runtime1.hpp"
#include "classfile/systemDictionary.hpp"
+ #include "gc/shared/barrierSet.hpp"
#include "gc/shared/barrierSetAssembler.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "interpreter/interpreter.hpp"
#include "oops/arrayOop.hpp"
#include "oops/markWord.hpp"
+ #include "runtime/arguments.hpp"
#include "runtime/basicLock.hpp"
#include "runtime/os.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
}
}
void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register tmp1, Register tmp2) {
assert_different_registers(obj, klass, len, tmp1, tmp2);
! if (UseCompactObjectHeaders) {
ld(tmp1, Address(klass, Klass::prototype_header_offset()));
sd(tmp1, Address(obj, oopDesc::mark_offset_in_bytes()));
} else {
! // This assumes that all prototype bits fitr in an int32_t
mv(tmp1, checked_cast<int32_t>(markWord::prototype().value()));
sd(tmp1, Address(obj, oopDesc::mark_offset_in_bytes()));
! encode_klass_not_null(tmp1, klass, tmp2);
sw(tmp1, Address(obj, oopDesc::klass_offset_in_bytes()));
}
if (len->is_valid()) {
sw(len, Address(obj, arrayOopDesc::length_offset_in_bytes()));
}
}
void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register tmp1, Register tmp2) {
assert_different_registers(obj, klass, len, tmp1, tmp2);
! if (UseCompactObjectHeaders || Arguments::is_valhalla_enabled()) {
+ // COH: Markword contains class pointer which is only known at runtime.
+ // Valhalla: Could have value class which has a different prototype header to a normal object.
+ // In both cases, we need to fetch dynamically.
ld(tmp1, Address(klass, Klass::prototype_header_offset()));
sd(tmp1, Address(obj, oopDesc::mark_offset_in_bytes()));
} else {
! // Otherwise: Can use the statically computed prototype header which is the same for every object.
mv(tmp1, checked_cast<int32_t>(markWord::prototype().value()));
sd(tmp1, Address(obj, oopDesc::mark_offset_in_bytes()));
! }
+
+ if (!UseCompactObjectHeaders) {
+ // COH: Markword already contains class pointer. Nothing else to do.
+ // Otherwise: Fetch klass pointer following the markword
+ encode_klass_not_null(tmp1, klass, tmp2); // Take care not to kill klass
sw(tmp1, Address(obj, oopDesc::klass_offset_in_bytes()));
}
if (len->is_valid()) {
sw(len, Address(obj, arrayOopDesc::length_offset_in_bytes()));
}
verify_oop(obj);
}
! void C1_MacroAssembler::build_frame(int framesize, int bang_size_in_bytes) {
! assert(bang_size_in_bytes >= framesize, "stack bang size incorrect");
// Make sure there is enough stack space for this method's activation.
// Note that we do this before creating a frame.
generate_stack_overflow_check(bang_size_in_bytes);
! MacroAssembler::build_frame(framesize);
// Insert nmethod entry barrier into frame.
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
bs->nmethod_entry_barrier(this, nullptr /* slow_path */, nullptr /* continuation */, nullptr /* guard */);
- }
! void C1_MacroAssembler::remove_frame(int framesize) {
! MacroAssembler::remove_frame(framesize);
}
-
void C1_MacroAssembler::verified_entry(bool breakAtEntry) {
// If we have to make this method not-entrant we'll overwrite its
// first instruction with a jump. For this action to be legal we
// must ensure that this first instruction is a J, JAL or NOP.
// Make it a NOP.
IncompressibleScope scope(this); // keep the nop as 4 bytes for patching.
assert_alignment(pc());
nop(); // 4 bytes
}
void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
// fp + -2: link
// + -1: return address
// + 0: argument with offset 0
// + 1: argument with offset 1
}
verify_oop(obj);
}
! void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes,
! int sp_offset_for_orig_pc,
+ bool needs_stack_repair, bool has_scalarized_args,
+ Label* verified_inline_entry_label) {
+ assert(bang_size_in_bytes >= frame_size_in_bytes, "stack bang size incorrect");
+
+ assert(!needs_stack_repair && !has_scalarized_args, "");
+
// Make sure there is enough stack space for this method's activation.
// Note that we do this before creating a frame.
generate_stack_overflow_check(bang_size_in_bytes);
! MacroAssembler::build_frame(frame_size_in_bytes);
// Insert nmethod entry barrier into frame.
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
bs->nmethod_entry_barrier(this, nullptr /* slow_path */, nullptr /* continuation */, nullptr /* guard */);
! if (verified_inline_entry_label != nullptr) {
! // Jump here from the scalarized entry points that already created the frame.
+ bind(*verified_inline_entry_label);
+ }
}
void C1_MacroAssembler::verified_entry(bool breakAtEntry) {
// If we have to make this method not-entrant we'll overwrite its
// first instruction with a jump. For this action to be legal we
// must ensure that this first instruction is a J, JAL or NOP.
// Make it a NOP.
IncompressibleScope scope(this); // keep the nop as 4 bytes for patching.
assert_alignment(pc());
nop(); // 4 bytes
}
+ int C1_MacroAssembler::scalarized_entry(const CompiledEntrySignature* ces, int frame_size_in_bytes, int bang_size_in_bytes,
+ int sp_offset_for_orig_pc, Label& verified_inline_entry_label, bool is_inline_ro_entry) {
+ Unimplemented();
+ return 0;
+ }
+
void C1_MacroAssembler::load_parameter(int offset_in_words, Register reg) {
// fp + -2: link
// + -1: return address
// + 0: argument with offset 0
// + 1: argument with offset 1
< prev index next >