< prev index next >

src/hotspot/cpu/ppc/templateInterpreterGenerator_ppc.cpp

Print this page

   1 /*
   2  * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2015, 2025 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *

 602 // This entry is returned to when a call returns to the interpreter.
 603 // When we arrive here, we expect that the callee stack frame is already popped.
 604 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {
 605   address entry = __ pc();
 606 
 607   // Move the value out of the return register back to the TOS cache of current frame.
 608   switch (state) {
 609     case ltos:
 610     case btos:
 611     case ztos:
 612     case ctos:
 613     case stos:
 614     case atos:
 615     case itos: __ mr(R17_tos, R3_RET); break;   // RET -> TOS cache
 616     case ftos:
 617     case dtos: __ fmr(F15_ftos, F1_RET); break; // TOS cache -> GR_FRET
 618     case vtos: break;                           // Nothing to do, this was a void return.
 619     default  : ShouldNotReachHere();
 620   }
 621 





 622   __ restore_interpreter_state(R11_scratch1, false /*bcp_and_mdx_only*/, true /*restore_top_frame_sp*/);
 623 
 624   // Compiled code destroys templateTableBase, reload.
 625   __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R12_scratch2);
 626 
 627   if (state == atos) {
 628     __ profile_return_type(R3_RET, R11_scratch1, R12_scratch2);
 629   }
 630 
 631   const Register cache = R11_scratch1;
 632   const Register size  = R12_scratch2;
 633   if (index_size == sizeof(u4)) {
 634     __ load_resolved_indy_entry(cache, size /* tmp */);
 635     __ lhz(size, in_bytes(ResolvedIndyEntry::num_parameters_offset()), cache);
 636   } else {
 637     assert(index_size == sizeof(u2), "Can only be u2");
 638     __ load_method_entry(cache, size /* tmp */);
 639     __ lhz(size, in_bytes(ResolvedMethodEntry::num_parameters_offset()), cache);
 640   }
 641   __ sldi(size, size, Interpreter::logStackElementSize);

1694   __ mr(R4_ARG2/*issuing_pc*/, return_pc);
1695 
1696   // Return to exception handler.
1697   __ blr();
1698 
1699   //=============================================================================
1700   // Counter overflow.
1701 
1702   if (inc_counter) {
1703     // Handle invocation counter overflow.
1704     __ bind(invocation_counter_overflow);
1705 
1706     generate_counter_overflow(continue_after_compile);
1707   }
1708 
1709   return entry;
1710 }
1711 
1712 // Generic interpreted method entry to (asm) interpreter.
1713 //
1714 address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized) {
1715   bool inc_counter = UseCompiler || CountCompiledCalls;
1716   address entry = __ pc();
1717   // Generate the code to allocate the interpreter stack frame.
1718   Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame.
1719            Rsize_of_locals     = R5_ARG3; // Written by generate_fixed_frame.
1720 
1721   // Does also a stack check to assure this frame fits on the stack.
1722   generate_fixed_frame(false, Rsize_of_parameters, Rsize_of_locals);
1723 
1724   // --------------------------------------------------------------------------
1725   // Zero out non-parameter locals.
1726   // Note: *Always* zero out non-parameter locals as Sparc does. It's not
1727   // worth to ask the flag, just do it.
1728   Register Rslot_addr = R6_ARG4,
1729            Rnum       = R7_ARG5;
1730   Label Lno_locals, Lzero_loop;
1731 
1732   // Set up the zeroing loop.
1733   __ subf(Rnum, Rsize_of_parameters, Rsize_of_locals);
1734   __ subf(Rslot_addr, Rsize_of_parameters, R18_locals);

1775 
1776     __ bind(continue_after_compile);
1777   }
1778 
1779   bang_stack_shadow_pages(false);
1780 
1781   if (inc_counter || ProfileInterpreter) {
1782     // Reset the _do_not_unlock_if_synchronized flag.
1783     if (synchronized) {
1784       __ li(R0, 0);
1785       __ stb(R0, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread);
1786     }
1787   }
1788 
1789   // --------------------------------------------------------------------------
1790   // Locking of synchronized methods. Must happen AFTER invocation_counter
1791   // check and stack overflow check, so method is not locked if overflows.
1792   if (synchronized) {
1793     lock_method(R3_ARG1, R4_ARG2, R5_ARG3);
1794   }

1795 #ifdef ASSERT
1796   else {
1797     Label Lok;
1798     __ lhz(R0, in_bytes(Method::access_flags_offset()), R19_method);
1799     __ andi_(R0, R0, JVM_ACC_SYNCHRONIZED);
1800     __ asm_assert_eq("method needs synchronization");
1801     __ bind(Lok);
1802   }
1803 #endif // ASSERT
1804 






1805   // --------------------------------------------------------------------------
1806   // JVMTI support
1807   __ notify_method_entry();
1808 
1809   // --------------------------------------------------------------------------
1810   // Start executing instructions.
1811   __ dispatch_next(vtos);
1812 
1813   // --------------------------------------------------------------------------
1814   if (inc_counter) {
1815     // Handle invocation counter overflow.
1816     __ bind(invocation_counter_overflow);
1817     generate_counter_overflow(continue_after_compile);
1818   }
1819   return entry;
1820 }
1821 
1822 // CRC32 Intrinsics.
1823 //
1824 // Contract on scratch and work registers.

   1 /*
   2  * Copyright (c) 2014, 2026, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2015, 2026 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *

 602 // This entry is returned to when a call returns to the interpreter.
 603 // When we arrive here, we expect that the callee stack frame is already popped.
 604 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, size_t index_size) {
 605   address entry = __ pc();
 606 
 607   // Move the value out of the return register back to the TOS cache of current frame.
 608   switch (state) {
 609     case ltos:
 610     case btos:
 611     case ztos:
 612     case ctos:
 613     case stos:
 614     case atos:
 615     case itos: __ mr(R17_tos, R3_RET); break;   // RET -> TOS cache
 616     case ftos:
 617     case dtos: __ fmr(F15_ftos, F1_RET); break; // TOS cache -> GR_FRET
 618     case vtos: break;                           // Nothing to do, this was a void return.
 619     default  : ShouldNotReachHere();
 620   }
 621 
 622   if (state == atos && InlineTypeReturnedAsFields) {
 623     __ unimplemented("return entry InlineTypeReturnedAsFields");
 624     //__ store_inline_type_fields_to_buf(nullptr, true);
 625   }
 626 
 627   __ restore_interpreter_state(R11_scratch1, false /*bcp_and_mdx_only*/, true /*restore_top_frame_sp*/);
 628 
 629   // Compiled code destroys templateTableBase, reload.
 630   __ load_const_optimized(R25_templateTableBase, (address)Interpreter::dispatch_table((TosState)0), R12_scratch2);
 631 
 632   if (state == atos) {
 633     __ profile_return_type(R3_RET, R11_scratch1, R12_scratch2);
 634   }
 635 
 636   const Register cache = R11_scratch1;
 637   const Register size  = R12_scratch2;
 638   if (index_size == sizeof(u4)) {
 639     __ load_resolved_indy_entry(cache, size /* tmp */);
 640     __ lhz(size, in_bytes(ResolvedIndyEntry::num_parameters_offset()), cache);
 641   } else {
 642     assert(index_size == sizeof(u2), "Can only be u2");
 643     __ load_method_entry(cache, size /* tmp */);
 644     __ lhz(size, in_bytes(ResolvedMethodEntry::num_parameters_offset()), cache);
 645   }
 646   __ sldi(size, size, Interpreter::logStackElementSize);

1699   __ mr(R4_ARG2/*issuing_pc*/, return_pc);
1700 
1701   // Return to exception handler.
1702   __ blr();
1703 
1704   //=============================================================================
1705   // Counter overflow.
1706 
1707   if (inc_counter) {
1708     // Handle invocation counter overflow.
1709     __ bind(invocation_counter_overflow);
1710 
1711     generate_counter_overflow(continue_after_compile);
1712   }
1713 
1714   return entry;
1715 }
1716 
1717 // Generic interpreted method entry to (asm) interpreter.
1718 //
1719 address TemplateInterpreterGenerator::generate_normal_entry(bool synchronized, bool object_init) {
1720   bool inc_counter = UseCompiler || CountCompiledCalls;
1721   address entry = __ pc();
1722   // Generate the code to allocate the interpreter stack frame.
1723   Register Rsize_of_parameters = R4_ARG2, // Written by generate_fixed_frame.
1724            Rsize_of_locals     = R5_ARG3; // Written by generate_fixed_frame.
1725 
1726   // Does also a stack check to assure this frame fits on the stack.
1727   generate_fixed_frame(false, Rsize_of_parameters, Rsize_of_locals);
1728 
1729   // --------------------------------------------------------------------------
1730   // Zero out non-parameter locals.
1731   // Note: *Always* zero out non-parameter locals as Sparc does. It's not
1732   // worth to ask the flag, just do it.
1733   Register Rslot_addr = R6_ARG4,
1734            Rnum       = R7_ARG5;
1735   Label Lno_locals, Lzero_loop;
1736 
1737   // Set up the zeroing loop.
1738   __ subf(Rnum, Rsize_of_parameters, Rsize_of_locals);
1739   __ subf(Rslot_addr, Rsize_of_parameters, R18_locals);

1780 
1781     __ bind(continue_after_compile);
1782   }
1783 
1784   bang_stack_shadow_pages(false);
1785 
1786   if (inc_counter || ProfileInterpreter) {
1787     // Reset the _do_not_unlock_if_synchronized flag.
1788     if (synchronized) {
1789       __ li(R0, 0);
1790       __ stb(R0, in_bytes(JavaThread::do_not_unlock_if_synchronized_offset()), R16_thread);
1791     }
1792   }
1793 
1794   // --------------------------------------------------------------------------
1795   // Locking of synchronized methods. Must happen AFTER invocation_counter
1796   // check and stack overflow check, so method is not locked if overflows.
1797   if (synchronized) {
1798     lock_method(R3_ARG1, R4_ARG2, R5_ARG3);
1799   }
1800 
1801 #ifdef ASSERT
1802   else {
1803     Label Lok;
1804     __ lhz(R0, in_bytes(Method::access_flags_offset()), R19_method);
1805     __ andi_(R0, R0, JVM_ACC_SYNCHRONIZED);
1806     __ asm_assert_eq("method needs synchronization");
1807     __ bind(Lok);
1808   }
1809 #endif // ASSERT
1810 
1811   // Issue a StoreStore barrier on entry to Object_init if the
1812   // class has strict field fields.  Be lazy, always do it.
1813   if (object_init) {
1814     __ membar(MacroAssembler::StoreStore);
1815   }
1816 
1817   // --------------------------------------------------------------------------
1818   // JVMTI support
1819   __ notify_method_entry();
1820 
1821   // --------------------------------------------------------------------------
1822   // Start executing instructions.
1823   __ dispatch_next(vtos);
1824 
1825   // --------------------------------------------------------------------------
1826   if (inc_counter) {
1827     // Handle invocation counter overflow.
1828     __ bind(invocation_counter_overflow);
1829     generate_counter_overflow(continue_after_compile);
1830   }
1831   return entry;
1832 }
1833 
1834 // CRC32 Intrinsics.
1835 //
1836 // Contract on scratch and work registers.
< prev index next >