diff --git a/src/hotspot/cpu/loongarch/continuationFreezeThaw_loongarch.inline.hpp b/src/hotspot/cpu/loongarch/continuationFreezeThaw_loongarch.inline.hpp index c4c49842464..dc61283c128 100644 --- a/src/hotspot/cpu/loongarch/continuationFreezeThaw_loongarch.inline.hpp +++ b/src/hotspot/cpu/loongarch/continuationFreezeThaw_loongarch.inline.hpp @@ -210,7 +210,7 @@ template frame ThawBase::new_stack_frame(const frame& hf, frame& intptr_t* heap_sp = hf.unextended_sp(); // If caller is interpreted it already made room for the callee arguments int overlap = caller.is_interpreted_frame() ? ContinuationHelper::InterpretedFrame::stack_argsize(hf) : 0; - const int fsize = ContinuationHelper::InterpretedFrame::frame_bottom(hf) - hf.unextended_sp() - overlap; + const int fsize = (int)(ContinuationHelper::InterpretedFrame::frame_bottom(hf) - hf.unextended_sp() - overlap); const int locals = hf.interpreter_frame_method()->max_locals(); intptr_t* frame_sp = caller.unextended_sp() - fsize; intptr_t* fp = frame_sp + (hf.fp() - heap_sp); diff --git a/src/hotspot/cpu/loongarch/frame_loongarch.inline.hpp b/src/hotspot/cpu/loongarch/frame_loongarch.inline.hpp index a740b3b1df3..02f7eb198b0 100644 --- a/src/hotspot/cpu/loongarch/frame_loongarch.inline.hpp +++ b/src/hotspot/cpu/loongarch/frame_loongarch.inline.hpp @@ -224,13 +224,13 @@ inline intptr_t* frame::real_fp() const { inline int frame::frame_size() const { return is_interpreted_frame() - ? sender_sp() - sp() + ? pointer_delta_as_int(sender_sp(), sp()) : cb()->frame_size(); } inline int frame::compiled_frame_stack_argsize() const { assert(cb()->is_compiled(), ""); - return (cb()->as_compiled_method()->method()->num_stack_arg_slots() * VMRegImpl::stack_slot_size) >> LogBytesPerWord; + return (cb()->as_nmethod()->num_stack_arg_slots() * VMRegImpl::stack_slot_size) >> LogBytesPerWord; } inline void frame::interpreted_frame_oop_map(InterpreterOopMap* mask) const { diff --git a/src/hotspot/cpu/loongarch/loongarch_64.ad b/src/hotspot/cpu/loongarch/loongarch_64.ad index 366df18eb9c..aeb924b2cb6 100644 --- a/src/hotspot/cpu/loongarch/loongarch_64.ad +++ b/src/hotspot/cpu/loongarch/loongarch_64.ad @@ -592,6 +592,10 @@ reg_class no_CR_reg %{ return _NO_CR_REG_mask; %} +reg_class no_FP_reg %{ + return _NO_FP_REG_mask; +%} + reg_class p_has_s6_reg %{ return _PTR_HAS_S6_REG_mask; %} @@ -799,6 +803,7 @@ extern RegMask _ANY_REG32_mask; extern RegMask _ANY_REG_mask; extern RegMask _PTR_REG_mask; extern RegMask _NO_CR_REG_mask; +extern RegMask _NO_FP_REG_mask; extern RegMask _PTR_HAS_S6_REG_mask; class CallStubImpl { @@ -878,6 +883,7 @@ RegMask _ANY_REG32_mask; RegMask _ANY_REG_mask; RegMask _PTR_REG_mask; RegMask _NO_CR_REG_mask; +RegMask _NO_FP_REG_mask; RegMask _PTR_HAS_S6_REG_mask; void reg_mask_init() { @@ -910,6 +916,9 @@ void reg_mask_init() { _NO_CR_REG_mask = _PTR_REG_mask; _NO_CR_REG_mask.SUBTRACT(_T0_LONG_REG_mask); + _NO_FP_REG_mask = _PTR_REG_mask; + _NO_FP_REG_mask.Remove(OptoReg::as_OptoReg(r22->as_VMReg())); + _PTR_HAS_S6_REG_mask.OR(_S6_LONG_REG_mask); } @@ -3648,6 +3657,17 @@ operand no_CR_mRegP() %{ interface(REG_INTER); %} +// This operand is not allowed to use FP even if +// FP is not used to hold the frame pointer. +operand no_FP_mRegP() %{ + constraint(ALLOC_IN_RC(no_FP_reg)); + match(RegP); + match(mRegP); + + format %{ %} + interface(REG_INTER); +%} + operand p_has_s6_mRegP() %{ constraint(ALLOC_IN_RC(p_has_s6_reg)); match(RegP); @@ -5384,7 +5404,9 @@ instruct loadConNKlass(mRegN dst, immNKlass src) %{ // Also known as an 'interprocedural jump'. // Target of jump will eventually return to caller. // TailJump below removes the return address. -instruct TailCalljmpInd(mRegP jump_target, s3_RegP method_ptr) %{ +// Don't use FP for 'jump_target' because a MachEpilogNode has already been +// emitted just above the TailCall which has reset FP to the caller state. +instruct TailCalljmpInd(no_FP_mRegP jump_target, s3_RegP method_ptr) %{ match(TailCall jump_target method_ptr); format %{ "JMP $jump_target \t# @TailCalljmpInd" %} @@ -11220,7 +11242,7 @@ instruct Ret() %{ // "restore" before this instruction (in Epilogue), we need to materialize it // in %i0. //FIXME -instruct tailjmpInd(mRegP jump_target, a0_RegP ex_oop, mA1RegI exception_pc) %{ +instruct tailjmpInd(no_FP_mRegP jump_target, a0_RegP ex_oop, mA1RegI exception_pc) %{ match( TailJump jump_target ex_oop ); ins_cost(200); format %{ "Jmp $jump_target ; ex_oop = $ex_oop #@tailjmpInd" %} diff --git a/src/hotspot/cpu/loongarch/register_loongarch.hpp b/src/hotspot/cpu/loongarch/register_loongarch.hpp index 25f7abfe75e..6ffdd41a5e7 100644 --- a/src/hotspot/cpu/loongarch/register_loongarch.hpp +++ b/src/hotspot/cpu/loongarch/register_loongarch.hpp @@ -55,7 +55,7 @@ class Register { public: // accessors - constexpr int raw_encoding() const { return this - first(); } + constexpr int raw_encoding() const { return checked_cast(this - first()); } constexpr int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); } constexpr bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; } @@ -225,7 +225,7 @@ class FloatRegister { public: // accessors - constexpr int raw_encoding() const { return this - first(); } + constexpr int raw_encoding() const { return checked_cast(this - first()); } constexpr int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); } constexpr bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; } @@ -386,7 +386,7 @@ class ConditionalFlagRegister { public: // accessors - int raw_encoding() const { return this - first(); } + int raw_encoding() const { return checked_cast(this - first()); } int encoding() const { assert(is_valid(), "invalid register"); return raw_encoding(); } bool is_valid() const { return 0 <= raw_encoding() && raw_encoding() < number_of_registers; } diff --git a/src/hotspot/cpu/loongarch/smallRegisterMap_loongarch.inline.hpp b/src/hotspot/cpu/loongarch/smallRegisterMap_loongarch.inline.hpp index ebd11807b24..7417ece8f8e 100644 --- a/src/hotspot/cpu/loongarch/smallRegisterMap_loongarch.inline.hpp +++ b/src/hotspot/cpu/loongarch/smallRegisterMap_loongarch.inline.hpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2022, Loongson Technology. All rights reserved. + * Copyright (c) 2022, 2024, Loongson Technology. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,8 +31,15 @@ // Java frames don't have callee saved registers (except for FP), so we can use a smaller RegisterMap class SmallRegisterMap { + constexpr SmallRegisterMap() = default; + ~SmallRegisterMap() = default; + NONCOPYABLE(SmallRegisterMap); + public: - static constexpr SmallRegisterMap* instance = nullptr; + static const SmallRegisterMap* instance() { + static constexpr SmallRegisterMap the_instance{}; + return &the_instance; + } private: static void assert_is_fp(VMReg r) NOT_DEBUG_RETURN DEBUG_ONLY({ assert (r == FP->as_VMReg() || r == FP->as_VMReg()->next(), "Reg: %s", r->name()); }) @@ -49,17 +56,6 @@ class SmallRegisterMap { return map; } - SmallRegisterMap() {} - - SmallRegisterMap(const RegisterMap* map) { - #ifdef ASSERT - for(int i = 0; i < RegisterMap::reg_count; i++) { - VMReg r = VMRegImpl::as_VMReg(i); - if (map->location(r, (intptr_t*)nullptr) != nullptr) assert_is_fp(r); - } - #endif - } - inline address location(VMReg reg, intptr_t* sp) const { assert_is_fp(reg); return (address)(sp - 2); diff --git a/src/hotspot/cpu/loongarch/stackChunkFrameStream_loongarch.inline.hpp b/src/hotspot/cpu/loongarch/stackChunkFrameStream_loongarch.inline.hpp index d329c43d661..0be80eb3e8a 100644 --- a/src/hotspot/cpu/loongarch/stackChunkFrameStream_loongarch.inline.hpp +++ b/src/hotspot/cpu/loongarch/stackChunkFrameStream_loongarch.inline.hpp @@ -35,7 +35,7 @@ template inline bool StackChunkFrameStream::is_in_frame(void* p0) const { assert(!is_done(), ""); intptr_t* p = (intptr_t*)p0; - int argsize = is_compiled() ? (_cb->as_compiled_method()->method()->num_stack_arg_slots() * VMRegImpl::stack_slot_size) >> LogBytesPerWord : 0; + int argsize = is_compiled() ? (_cb->as_nmethod()->num_stack_arg_slots() * VMRegImpl::stack_slot_size) >> LogBytesPerWord : 0; int frame_size = _cb->frame_size() + argsize; return p == sp() - 2 || ((p - unextended_sp()) >= 0 && (p - unextended_sp()) < frame_size); } @@ -115,8 +115,8 @@ inline int StackChunkFrameStream::interpreter_frame_num_oops() const f.interpreted_frame_oop_map(&mask); return mask.num_oops() + 1 // for the mirror oop - + ((intptr_t*)f.interpreter_frame_monitor_begin() - - (intptr_t*)f.interpreter_frame_monitor_end()) / BasicObjectLock::size(); + + pointer_delta_as_int((intptr_t*)f.interpreter_frame_monitor_begin(), + (intptr_t*)f.interpreter_frame_monitor_end()) / BasicObjectLock::size(); } template<>