hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp
changeset 38209 b2a58604e046
parent 38190 ff9ac612c723
child 38246 518c89421883
equal deleted inserted replaced
38208:ff63d43b0480 38209:b2a58604e046
     1 /*
     1 /*
     2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    61 
    61 
    62 static const Register& Lstub_temp = L2;
    62 static const Register& Lstub_temp = L2;
    63 
    63 
    64 // -------------------------------------------------------------------------------------------------------------------------
    64 // -------------------------------------------------------------------------------------------------------------------------
    65 // Stub Code definitions
    65 // Stub Code definitions
    66 
       
    67 static address handle_unsafe_access() {
       
    68   JavaThread* thread = JavaThread::current();
       
    69   address pc  = thread->saved_exception_pc();
       
    70   address npc = thread->saved_exception_npc();
       
    71   // pc is the instruction which we must emulate
       
    72   // doing a no-op is fine:  return garbage from the load
       
    73 
       
    74   // request an async exception
       
    75   thread->set_pending_unsafe_access_error();
       
    76 
       
    77   // return address of next instruction to execute
       
    78   return npc;
       
    79 }
       
    80 
    66 
    81 class StubGenerator: public StubCodeGenerator {
    67 class StubGenerator: public StubCodeGenerator {
    82  private:
    68  private:
    83 
    69 
    84 #ifdef PRODUCT
    70 #ifdef PRODUCT
   742     __ delayed()->add(O0, O2, O0); // note that cas made O2==O3
   728     __ delayed()->add(O0, O2, O0); // note that cas made O2==O3
   743 
   729 
   744     return start;
   730     return start;
   745   }
   731   }
   746   Label _atomic_add_stub;  // called from other stubs
   732   Label _atomic_add_stub;  // called from other stubs
   747 
       
   748 
       
   749   //------------------------------------------------------------------------------------------------------------------------
       
   750   // The following routine generates a subroutine to throw an asynchronous
       
   751   // UnknownError when an unsafe access gets a fault that could not be
       
   752   // reasonably prevented by the programmer.  (Example: SIGBUS/OBJERR.)
       
   753   //
       
   754   // Arguments :
       
   755   //
       
   756   //      trapping PC:    O7
       
   757   //
       
   758   // Results:
       
   759   //     posts an asynchronous exception, skips the trapping instruction
       
   760   //
       
   761 
       
   762   address generate_handler_for_unsafe_access() {
       
   763     StubCodeMark mark(this, "StubRoutines", "handler_for_unsafe_access");
       
   764     address start = __ pc();
       
   765 
       
   766     const int preserve_register_words = (64 * 2);
       
   767     Address preserve_addr(FP, (-preserve_register_words * wordSize) + STACK_BIAS);
       
   768 
       
   769     Register Lthread = L7_thread_cache;
       
   770     int i;
       
   771 
       
   772     __ save_frame(0);
       
   773     __ mov(G1, L1);
       
   774     __ mov(G2, L2);
       
   775     __ mov(G3, L3);
       
   776     __ mov(G4, L4);
       
   777     __ mov(G5, L5);
       
   778     for (i = 0; i < 64; i += 2) {
       
   779       __ stf(FloatRegisterImpl::D, as_FloatRegister(i), preserve_addr, i * wordSize);
       
   780     }
       
   781 
       
   782     address entry_point = CAST_FROM_FN_PTR(address, handle_unsafe_access);
       
   783     BLOCK_COMMENT("call handle_unsafe_access");
       
   784     __ call(entry_point, relocInfo::runtime_call_type);
       
   785     __ delayed()->nop();
       
   786 
       
   787     __ mov(L1, G1);
       
   788     __ mov(L2, G2);
       
   789     __ mov(L3, G3);
       
   790     __ mov(L4, G4);
       
   791     __ mov(L5, G5);
       
   792     for (i = 0; i < 64; i += 2) {
       
   793       __ ldf(FloatRegisterImpl::D, preserve_addr, as_FloatRegister(i), i * wordSize);
       
   794     }
       
   795 
       
   796     __ verify_thread();
       
   797 
       
   798     __ jmp(O0, 0);
       
   799     __ delayed()->restore();
       
   800 
       
   801     return start;
       
   802   }
       
   803 
   733 
   804 
   734 
   805   // Support for uint StubRoutine::Sparc::partial_subtype_check( Klass sub, Klass super );
   735   // Support for uint StubRoutine::Sparc::partial_subtype_check( Klass sub, Klass super );
   806   // Arguments :
   736   // Arguments :
   807   //
   737   //
  5378     // These entry points require SharedInfo::stack0 to be set up in non-core builds
  5308     // These entry points require SharedInfo::stack0 to be set up in non-core builds
  5379     StubRoutines::_throw_AbstractMethodError_entry         = generate_throw_exception("AbstractMethodError throw_exception",          CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError));
  5309     StubRoutines::_throw_AbstractMethodError_entry         = generate_throw_exception("AbstractMethodError throw_exception",          CAST_FROM_FN_PTR(address, SharedRuntime::throw_AbstractMethodError));
  5380     StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError));
  5310     StubRoutines::_throw_IncompatibleClassChangeError_entry= generate_throw_exception("IncompatibleClassChangeError throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_IncompatibleClassChangeError));
  5381     StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call));
  5311     StubRoutines::_throw_NullPointerException_at_call_entry= generate_throw_exception("NullPointerException at call throw_exception", CAST_FROM_FN_PTR(address, SharedRuntime::throw_NullPointerException_at_call));
  5382 
  5312 
  5383     StubRoutines::_handler_for_unsafe_access_entry =
       
  5384       generate_handler_for_unsafe_access();
       
  5385 
       
  5386     // support for verify_oop (must happen after universe_init)
  5313     // support for verify_oop (must happen after universe_init)
  5387     StubRoutines::_verify_oop_subroutine_entry     = generate_verify_oop_subroutine();
  5314     StubRoutines::_verify_oop_subroutine_entry     = generate_verify_oop_subroutine();
  5388 
  5315 
  5389     // arraycopy stubs used by compilers
  5316     // arraycopy stubs used by compilers
  5390     generate_arraycopy_stubs();
  5317     generate_arraycopy_stubs();