src/hotspot/cpu/s390/c1_Runtime1_s390.cpp
author pliden
Thu, 12 Apr 2018 08:25:56 +0200
changeset 49752 93d84f667d12
parent 49455 848864ed9b17
child 49754 ee93c1087584
permissions -rw-r--r--
8201318: Introduce GCThreadLocalData to abstract GC-specific data belonging to a thread Reviewed-by: shade, rehn
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     1
/*
49164
7e958a8ebcd3 8195142: Refactor out card table from CardTableModRefBS to flatten the BarrierSet hierarchy
eosterlund
parents: 49010
diff changeset
     2
 * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     3
 * Copyright (c) 2016 SAP SE. All rights reserved.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     4
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     5
 *
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     6
 * This code is free software; you can redistribute it and/or modify it
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     7
 * under the terms of the GNU General Public License version 2 only, as
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     8
 * published by the Free Software Foundation.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
     9
 *
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    10
 * This code is distributed in the hope that it will be useful, but WITHOUT
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    13
 * version 2 for more details (a copy is included in the LICENSE file that
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    14
 * accompanied this code).
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    15
 *
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    16
 * You should have received a copy of the GNU General Public License version
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    17
 * 2 along with this work; if not, write to the Free Software Foundation,
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    18
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    19
 *
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    20
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    21
 * or visit www.oracle.com if you need additional information or have any
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    22
 * questions.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    23
 *
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    24
 */
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    25
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    26
#include "precompiled.hpp"
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    27
#include "c1/c1_Defs.hpp"
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    28
#include "c1/c1_MacroAssembler.hpp"
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    29
#include "c1/c1_Runtime1.hpp"
49164
7e958a8ebcd3 8195142: Refactor out card table from CardTableModRefBS to flatten the BarrierSet hierarchy
eosterlund
parents: 49010
diff changeset
    30
#include "ci/ciUtilities.hpp"
7e958a8ebcd3 8195142: Refactor out card table from CardTableModRefBS to flatten the BarrierSet hierarchy
eosterlund
parents: 49010
diff changeset
    31
#include "gc/shared/cardTable.hpp"
49455
848864ed9b17 8199604: Rename CardTableModRefBS to CardTableBarrierSet
eosterlund
parents: 49347
diff changeset
    32
#include "gc/shared/cardTableBarrierSet.hpp"
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    33
#include "interpreter/interpreter.hpp"
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    34
#include "nativeInst_s390.hpp"
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    35
#include "oops/compiledICHolder.hpp"
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    36
#include "oops/oop.inline.hpp"
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    37
#include "prims/jvmtiExport.hpp"
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    38
#include "register_s390.hpp"
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    39
#include "runtime/sharedRuntime.hpp"
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    40
#include "runtime/signature.hpp"
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    41
#include "runtime/vframeArray.hpp"
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    42
#include "utilities/macros.hpp"
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    43
#include "vmreg_s390.inline.hpp"
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    44
#include "registerSaver_s390.hpp"
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    45
#if INCLUDE_ALL_GCS
49347
edb65305d3ac 8195148: Collapse G1SATBCardTableModRefBS and G1SATBCardTableLoggingModRefBS into a single G1BarrierSet
eosterlund
parents: 49164
diff changeset
    46
#include "gc/g1/g1BarrierSet.hpp"
49164
7e958a8ebcd3 8195142: Refactor out card table from CardTableModRefBS to flatten the BarrierSet hierarchy
eosterlund
parents: 49010
diff changeset
    47
#include "gc/g1/g1CardTable.hpp"
49752
93d84f667d12 8201318: Introduce GCThreadLocalData to abstract GC-specific data belonging to a thread
pliden
parents: 49455
diff changeset
    48
#include "gc/g1/g1ThreadLocalData.hpp"
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    49
#endif
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    50
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    51
// Implementation of StubAssembler
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    52
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    53
int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry_point, int number_of_arguments) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    54
  set_num_rt_args(0); // Nothing on stack.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    55
  assert(!(oop_result1->is_valid() || metadata_result->is_valid()) || oop_result1 != metadata_result, "registers must be different");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    56
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    57
  // We cannot trust that code generated by the C++ compiler saves R14
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    58
  // to z_abi_160.return_pc, because sometimes it spills R14 using stmg at
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    59
  // z_abi_160.gpr14 (e.g. InterpreterRuntime::_new()).
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    60
  // Therefore we load the PC into Z_R1_scratch and let set_last_Java_frame() save
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    61
  // it into the frame anchor.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    62
  address pc = get_PC(Z_R1_scratch);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    63
  int call_offset = (int)(pc - addr_at(0));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    64
  set_last_Java_frame(Z_SP, Z_R1_scratch);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    65
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    66
  // ARG1 must hold thread address.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    67
  z_lgr(Z_ARG1, Z_thread);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    68
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    69
  address return_pc = NULL;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    70
  align_call_far_patchable(this->pc());
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    71
  return_pc = call_c_opt(entry_point);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    72
  assert(return_pc != NULL, "const section overflow");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    73
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    74
  reset_last_Java_frame();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    75
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    76
  // Check for pending exceptions.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    77
  {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    78
    load_and_test_long(Z_R0_scratch, Address(Z_thread, Thread::pending_exception_offset()));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    79
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    80
    // This used to conditionally jump to forward_exception however it is
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    81
    // possible if we relocate that the branch will not reach. So we must jump
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    82
    // around so we can always reach.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    83
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    84
    Label ok;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    85
    z_bre(ok); // Bcondequal is the same as bcondZero.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    86
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    87
    // exception pending => forward to exception handler
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    88
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    89
    // Make sure that the vm_results are cleared.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    90
    if (oop_result1->is_valid()) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    91
      clear_mem(Address(Z_thread, JavaThread::vm_result_offset()), sizeof(jlong));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    92
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    93
    if (metadata_result->is_valid()) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    94
      clear_mem(Address(Z_thread, JavaThread::vm_result_2_offset()), sizeof(jlong));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    95
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    96
    if (frame_size() == no_frame_size) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    97
      // Pop the stub frame.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    98
      pop_frame();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
    99
      restore_return_pc();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   100
      load_const_optimized(Z_R1, StubRoutines::forward_exception_entry());
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   101
      z_br(Z_R1);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   102
    } else if (_stub_id == Runtime1::forward_exception_id) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   103
      should_not_reach_here();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   104
    } else {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   105
      load_const_optimized(Z_R1, Runtime1::entry_for (Runtime1::forward_exception_id));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   106
      z_br(Z_R1);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   107
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   108
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   109
    bind(ok);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   110
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   111
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   112
  // Get oop results if there are any and reset the values in the thread.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   113
  if (oop_result1->is_valid()) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   114
    get_vm_result(oop_result1);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   115
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   116
  if (metadata_result->is_valid()) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   117
    get_vm_result_2(metadata_result);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   118
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   119
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   120
  return call_offset;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   121
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   122
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   123
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   124
int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   125
  // Z_ARG1 is reserved for the thread.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   126
  lgr_if_needed(Z_ARG2, arg1);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   127
  return call_RT(oop_result1, metadata_result, entry, 1);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   128
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   129
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   130
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   131
int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   132
  // Z_ARG1 is reserved for the thread.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   133
  lgr_if_needed(Z_ARG2, arg1);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   134
  assert(arg2 != Z_ARG2, "smashed argument");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   135
  lgr_if_needed(Z_ARG3, arg2);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   136
  return call_RT(oop_result1, metadata_result, entry, 2);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   137
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   138
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   139
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   140
int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2, Register arg3) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   141
  // Z_ARG1 is reserved for the thread.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   142
  lgr_if_needed(Z_ARG2, arg1);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   143
  assert(arg2 != Z_ARG2, "smashed argument");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   144
  lgr_if_needed(Z_ARG3, arg2);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   145
  assert(arg3 != Z_ARG3, "smashed argument");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   146
  lgr_if_needed(Z_ARG4, arg3);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   147
  return call_RT(oop_result1, metadata_result, entry, 3);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   148
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   149
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   150
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   151
// Implementation of Runtime1
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   152
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   153
#define __ sasm->
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   154
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   155
#ifndef PRODUCT
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   156
#undef  __
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   157
#define __ (Verbose ? (sasm->block_comment(FILE_AND_LINE),sasm):sasm)->
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   158
#endif // !PRODUCT
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   159
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   160
#define BLOCK_COMMENT(str) if (PrintAssembly) __ block_comment(str)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   161
#define BIND(label)        bind(label); BLOCK_COMMENT(#label ":")
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   162
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   163
static OopMap* generate_oop_map(StubAssembler* sasm) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   164
  RegisterSaver::RegisterSet reg_set = RegisterSaver::all_registers;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   165
  int frame_size_in_slots =
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   166
    RegisterSaver::live_reg_frame_size(reg_set) / VMRegImpl::stack_slot_size;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   167
  sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   168
  return RegisterSaver::generate_oop_map(sasm, reg_set);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   169
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   170
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   171
static OopMap* save_live_registers(StubAssembler* sasm, bool save_fpu_registers = true, Register return_pc = Z_R14) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   172
  __ block_comment("save_live_registers");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   173
  RegisterSaver::RegisterSet reg_set =
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   174
    save_fpu_registers ? RegisterSaver::all_registers : RegisterSaver::all_integer_registers;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   175
  int frame_size_in_slots =
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   176
    RegisterSaver::live_reg_frame_size(reg_set) / VMRegImpl::stack_slot_size;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   177
  sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   178
  return RegisterSaver::save_live_registers(sasm, reg_set, return_pc);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   179
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   180
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   181
static OopMap* save_live_registers_except_r2(StubAssembler* sasm, bool save_fpu_registers = true) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   182
  if (!save_fpu_registers) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   183
    __ unimplemented(FILE_AND_LINE);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   184
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   185
  __ block_comment("save_live_registers");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   186
  RegisterSaver::RegisterSet reg_set = RegisterSaver::all_registers_except_r2;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   187
  int frame_size_in_slots =
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   188
      RegisterSaver::live_reg_frame_size(reg_set) / VMRegImpl::stack_slot_size;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   189
  sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   190
  return RegisterSaver::save_live_registers(sasm, reg_set);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   191
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   192
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   193
static OopMap* save_volatile_registers(StubAssembler* sasm, Register return_pc = Z_R14) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   194
  __ block_comment("save_volatile_registers");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   195
  RegisterSaver::RegisterSet reg_set = RegisterSaver::all_volatile_registers;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   196
  int frame_size_in_slots =
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   197
    RegisterSaver::live_reg_frame_size(reg_set) / VMRegImpl::stack_slot_size;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   198
  sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   199
  return RegisterSaver::save_live_registers(sasm, reg_set, return_pc);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   200
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   201
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   202
static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   203
  __ block_comment("restore_live_registers");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   204
  RegisterSaver::RegisterSet reg_set =
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   205
    restore_fpu_registers ? RegisterSaver::all_registers : RegisterSaver::all_integer_registers;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   206
  RegisterSaver::restore_live_registers(sasm, reg_set);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   207
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   208
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   209
static void restore_live_registers_except_r2(StubAssembler* sasm, bool restore_fpu_registers = true) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   210
  if (!restore_fpu_registers) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   211
    __ unimplemented(FILE_AND_LINE);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   212
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   213
  __ block_comment("restore_live_registers_except_r2");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   214
  RegisterSaver::restore_live_registers(sasm, RegisterSaver::all_registers_except_r2);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   215
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   216
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   217
static void restore_volatile_registers(StubAssembler* sasm) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   218
  __ block_comment("restore_volatile_registers");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   219
  RegisterSaver::RegisterSet reg_set = RegisterSaver::all_volatile_registers;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   220
  RegisterSaver::restore_live_registers(sasm, reg_set);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   221
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   222
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   223
void Runtime1::initialize_pd() {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   224
  // Nothing to do.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   225
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   226
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   227
OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   228
  // Make a frame and preserve the caller's caller-save registers.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   229
  OopMap* oop_map = save_live_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   230
  int call_offset;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   231
  if (!has_argument) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   232
    call_offset = __ call_RT(noreg, noreg, target);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   233
  } else {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   234
    call_offset = __ call_RT(noreg, noreg, target, Z_R1_scratch, Z_R0_scratch);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   235
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   236
  OopMapSet* oop_maps = new OopMapSet();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   237
  oop_maps->add_gc_map(call_offset, oop_map);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   238
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   239
  __ should_not_reach_here();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   240
  return oop_maps;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   241
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   242
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   243
void Runtime1::generate_unwind_exception(StubAssembler *sasm) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   244
  // Incoming parameters: Z_EXC_OOP and Z_EXC_PC.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   245
  // Keep copies in callee-saved registers during runtime call.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   246
  const Register exception_oop_callee_saved = Z_R11;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   247
  const Register exception_pc_callee_saved = Z_R12;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   248
  // Other registers used in this stub.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   249
  const Register handler_addr = Z_R4;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   250
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   251
  // Verify that only exception_oop, is valid at this time.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   252
  __ invalidate_registers(Z_EXC_OOP, Z_EXC_PC);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   253
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   254
  // Check that fields in JavaThread for exception oop and issuing pc are set.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   255
  __ asm_assert_mem8_is_zero(in_bytes(JavaThread::exception_oop_offset()), Z_thread, "exception oop already set : " FILE_AND_LINE, 0);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   256
  __ asm_assert_mem8_is_zero(in_bytes(JavaThread::exception_pc_offset()), Z_thread, "exception pc already set : " FILE_AND_LINE, 0);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   257
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   258
  // Save exception_oop and pc in callee-saved register to preserve it
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   259
  // during runtime calls.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   260
  __ verify_not_null_oop(Z_EXC_OOP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   261
  __ lgr_if_needed(exception_oop_callee_saved, Z_EXC_OOP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   262
  __ lgr_if_needed(exception_pc_callee_saved, Z_EXC_PC);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   263
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   264
  __ push_frame_abi160(0); // Runtime code needs the z_abi_160.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   265
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   266
  // Search the exception handler address of the caller (using the return address).
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   267
  __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), Z_thread, Z_EXC_PC);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   268
  // Z_RET(Z_R2): exception handler address of the caller.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   269
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   270
  __ pop_frame();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   271
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   272
  __ invalidate_registers(exception_oop_callee_saved, exception_pc_callee_saved, Z_RET);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   273
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   274
  // Move result of call into correct register.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   275
  __ lgr_if_needed(handler_addr, Z_RET);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   276
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   277
  // Restore exception oop and pc to Z_EXC_OOP and Z_EXC_PC (required convention of exception handler).
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   278
  __ lgr_if_needed(Z_EXC_OOP, exception_oop_callee_saved);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   279
  __ lgr_if_needed(Z_EXC_PC, exception_pc_callee_saved);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   280
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   281
  // Verify that there is really a valid exception in Z_EXC_OOP.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   282
  __ verify_not_null_oop(Z_EXC_OOP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   283
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   284
  __ z_br(handler_addr); // Jump to exception handler.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   285
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   286
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   287
OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   288
  // Make a frame and preserve the caller's caller-save registers.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   289
  OopMap* oop_map = save_live_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   290
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   291
  // Call the runtime patching routine, returns non-zero if nmethod got deopted.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   292
  int call_offset = __ call_RT(noreg, noreg, target);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   293
  OopMapSet* oop_maps = new OopMapSet();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   294
  oop_maps->add_gc_map(call_offset, oop_map);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   295
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   296
  // Re-execute the patched instruction or, if the nmethod was
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   297
  // deoptmized, return to the deoptimization handler entry that will
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   298
  // cause re-execution of the current bytecode.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   299
  DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   300
  assert(deopt_blob != NULL, "deoptimization blob must have been created");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   301
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   302
  __ z_ltr(Z_RET, Z_RET); // return value == 0
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   303
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   304
  restore_live_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   305
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   306
  __ z_bcr(Assembler::bcondZero, Z_R14);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   307
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   308
  // Return to the deoptimization handler entry for unpacking and
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   309
  // rexecute if we simply returned then we'd deopt as if any call we
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   310
  // patched had just returned.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   311
  AddressLiteral dest(deopt_blob->unpack_with_reexecution());
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   312
  __ load_const_optimized(Z_R1_scratch, dest);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   313
  __ z_br(Z_R1_scratch);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   314
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   315
  return oop_maps;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   316
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   317
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   318
OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   319
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   320
  // for better readability
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   321
  const bool must_gc_arguments = true;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   322
  const bool dont_gc_arguments = false;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   323
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   324
  // Default value; overwritten for some optimized stubs that are
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   325
  // called from methods that do not use the fpu.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   326
  bool save_fpu_registers = true;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   327
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   328
  // Stub code and info for the different stubs.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   329
  OopMapSet* oop_maps = NULL;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   330
  switch (id) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   331
    case forward_exception_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   332
      {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   333
        oop_maps = generate_handle_exception(id, sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   334
        // will not return
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   335
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   336
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   337
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   338
    case new_instance_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   339
    case fast_new_instance_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   340
    case fast_new_instance_init_check_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   341
      {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   342
        Register klass    = Z_R11; // Incoming
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   343
        Register obj      = Z_R2;  // Result
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   344
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   345
        if (id == new_instance_id) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   346
          __ set_info("new_instance", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   347
        } else if (id == fast_new_instance_id) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   348
          __ set_info("fast new_instance", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   349
        } else {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   350
          assert(id == fast_new_instance_init_check_id, "bad StubID");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   351
          __ set_info("fast new_instance init check", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   352
        }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   353
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   354
        OopMap* map = save_live_registers_except_r2(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   355
        int call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   356
        oop_maps = new OopMapSet();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   357
        oop_maps->add_gc_map(call_offset, map);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   358
        restore_live_registers_except_r2(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   359
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   360
        __ verify_oop(obj);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   361
        __ z_br(Z_R14);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   362
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   363
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   364
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   365
    case counter_overflow_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   366
      {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   367
        // Arguments :
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   368
        //   bci    : stack param 0
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   369
        //   method : stack param 1
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   370
        //
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   371
        Register bci = Z_ARG2, method = Z_ARG3;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   372
        // frame size in bytes
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   373
        OopMap* map = save_live_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   374
        const int frame_size = sasm->frame_size() * VMRegImpl::slots_per_word * VMRegImpl::stack_slot_size;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   375
        __ z_lg(bci,    0*BytesPerWord + FrameMap::first_available_sp_in_frame + frame_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   376
        __ z_lg(method, 1*BytesPerWord + FrameMap::first_available_sp_in_frame + frame_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   377
        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   378
        oop_maps = new OopMapSet();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   379
        oop_maps->add_gc_map(call_offset, map);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   380
        restore_live_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   381
        __ z_br(Z_R14);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   382
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   383
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   384
    case new_type_array_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   385
    case new_object_array_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   386
      {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   387
        Register length   = Z_R13; // Incoming
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   388
        Register klass    = Z_R11; // Incoming
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   389
        Register obj      = Z_R2;  // Result
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   390
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   391
        if (id == new_type_array_id) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   392
          __ set_info("new_type_array", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   393
        } else {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   394
          __ set_info("new_object_array", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   395
        }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   396
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   397
#ifdef ASSERT
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   398
        // Assert object type is really an array of the proper kind.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   399
        {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   400
          NearLabel ok;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   401
          Register t0 = obj;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   402
          __ mem2reg_opt(t0, Address(klass, Klass::layout_helper_offset()), false);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   403
          __ z_sra(t0, Klass::_lh_array_tag_shift);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   404
          int tag = ((id == new_type_array_id)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   405
                     ? Klass::_lh_array_tag_type_value
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   406
                     : Klass::_lh_array_tag_obj_value);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   407
          __ compare32_and_branch(t0, tag, Assembler::bcondEqual, ok);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   408
          __ stop("assert(is an array klass)");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   409
          __ should_not_reach_here();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   410
          __ bind(ok);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   411
        }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   412
#endif // ASSERT
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   413
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   414
        OopMap* map = save_live_registers_except_r2(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   415
        int call_offset;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   416
        if (id == new_type_array_id) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   417
          call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   418
        } else {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   419
          call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   420
        }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   421
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   422
        oop_maps = new OopMapSet();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   423
        oop_maps->add_gc_map(call_offset, map);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   424
        restore_live_registers_except_r2(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   425
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   426
        __ verify_oop(obj);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   427
        __ z_br(Z_R14);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   428
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   429
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   430
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   431
    case new_multi_array_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   432
      { __ set_info("new_multi_array", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   433
        // Z_R3,: klass
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   434
        // Z_R4,: rank
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   435
        // Z_R5: address of 1st dimension
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   436
        OopMap* map = save_live_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   437
        int call_offset = __ call_RT(Z_R2, noreg, CAST_FROM_FN_PTR(address, new_multi_array), Z_R3, Z_R4, Z_R5);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   438
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   439
        oop_maps = new OopMapSet();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   440
        oop_maps->add_gc_map(call_offset, map);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   441
        restore_live_registers_except_r2(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   442
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   443
        // Z_R2,: new multi array
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   444
        __ verify_oop(Z_R2);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   445
        __ z_br(Z_R14);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   446
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   447
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   448
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   449
    case register_finalizer_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   450
      {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   451
        __ set_info("register_finalizer", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   452
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   453
        // Load the klass and check the has finalizer flag.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   454
        Register klass = Z_ARG2;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   455
        __ load_klass(klass, Z_ARG1);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   456
        __ testbit(Address(klass, Klass::access_flags_offset()), exact_log2(JVM_ACC_HAS_FINALIZER));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   457
        __ z_bcr(Assembler::bcondAllZero, Z_R14); // Return if bit is not set.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   458
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   459
        OopMap* oop_map = save_live_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   460
        int call_offset = __ call_RT(noreg, noreg,
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   461
                                     CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), Z_ARG1);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   462
        oop_maps = new OopMapSet();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   463
        oop_maps->add_gc_map(call_offset, oop_map);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   464
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   465
        // Now restore all the live registers.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   466
        restore_live_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   467
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   468
        __ z_br(Z_R14);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   469
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   470
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   471
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   472
    case throw_range_check_failed_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   473
      { __ set_info("range_check_failed", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   474
        oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_range_check_exception), true);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   475
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   476
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   477
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   478
    case throw_index_exception_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   479
      { __ set_info("index_range_check_failed", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   480
        oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_index_exception), true);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   481
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   482
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   483
    case throw_div0_exception_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   484
      { __ set_info("throw_div0_exception", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   485
        oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_div0_exception), false);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   486
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   487
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   488
    case throw_null_pointer_exception_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   489
      { __ set_info("throw_null_pointer_exception", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   490
        oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   491
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   492
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   493
    case handle_exception_nofpu_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   494
    case handle_exception_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   495
      { __ set_info("handle_exception", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   496
        oop_maps = generate_handle_exception(id, sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   497
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   498
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   499
    case handle_exception_from_callee_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   500
      { __ set_info("handle_exception_from_callee", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   501
        oop_maps = generate_handle_exception(id, sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   502
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   503
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   504
    case unwind_exception_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   505
      { __ set_info("unwind_exception", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   506
        // Note: no stubframe since we are about to leave the current
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   507
        // activation and we are calling a leaf VM function only.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   508
        generate_unwind_exception(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   509
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   510
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   511
    case throw_array_store_exception_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   512
      { __ set_info("throw_array_store_exception", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   513
        oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   514
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   515
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   516
    case throw_class_cast_exception_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   517
    { // Z_R1_scratch: object
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   518
      __ set_info("throw_class_cast_exception", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   519
      oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   520
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   521
    break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   522
    case throw_incompatible_class_change_error_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   523
      { __ set_info("throw_incompatible_class_cast_exception", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   524
        oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   525
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   526
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   527
    case slow_subtype_check_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   528
    {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   529
      // Arguments :
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   530
      //   sub  : stack param 0
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   531
      //   super: stack param 1
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   532
      //   raddr: Z_R14, blown by call
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   533
      //
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   534
      // Result : condition code 0 for match (bcondEqual will be true),
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   535
      //          condition code 2 for miss  (bcondNotEqual will be true)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   536
      NearLabel miss;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   537
      const Register Rsubklass   = Z_ARG2; // sub
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   538
      const Register Rsuperklass = Z_ARG3; // super
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   539
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   540
      // No args, but tmp registers that are killed.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   541
      const Register Rlength     = Z_ARG4; // cache array length
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   542
      const Register Rarray_ptr  = Z_ARG5; // Current value from cache array.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   543
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   544
      if (UseCompressedOops) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   545
        assert(Universe::heap() != NULL, "java heap must be initialized to generate partial_subtype_check stub");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   546
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   547
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   548
      const int frame_size = 4*BytesPerWord + frame::z_abi_160_size;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   549
      // Save return pc. This is not necessary, but could be helpful
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   550
      // in the case of crashes.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   551
      __ save_return_pc();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   552
      __ push_frame(frame_size);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   553
      // Save registers before changing them.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   554
      int i = 0;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   555
      __ z_stg(Rsubklass,   (i++)*BytesPerWord + frame::z_abi_160_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   556
      __ z_stg(Rsuperklass, (i++)*BytesPerWord + frame::z_abi_160_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   557
      __ z_stg(Rlength,     (i++)*BytesPerWord + frame::z_abi_160_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   558
      __ z_stg(Rarray_ptr,  (i++)*BytesPerWord + frame::z_abi_160_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   559
      assert(i*BytesPerWord + frame::z_abi_160_size == frame_size, "check");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   560
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   561
      // Get sub and super from stack.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   562
      __ z_lg(Rsubklass,   0*BytesPerWord + FrameMap::first_available_sp_in_frame + frame_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   563
      __ z_lg(Rsuperklass, 1*BytesPerWord + FrameMap::first_available_sp_in_frame + frame_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   564
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   565
      __ check_klass_subtype_slow_path(Rsubklass, Rsuperklass, Rarray_ptr, Rlength, NULL, &miss);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   566
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   567
      // Match falls through here.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   568
      i = 0;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   569
      __ z_lg(Rsubklass,   (i++)*BytesPerWord + frame::z_abi_160_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   570
      __ z_lg(Rsuperklass, (i++)*BytesPerWord + frame::z_abi_160_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   571
      __ z_lg(Rlength,     (i++)*BytesPerWord + frame::z_abi_160_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   572
      __ z_lg(Rarray_ptr,  (i++)*BytesPerWord + frame::z_abi_160_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   573
      assert(i*BytesPerWord + frame::z_abi_160_size == frame_size, "check");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   574
      __ pop_frame();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   575
      // Return pc is still in R_14.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   576
      __ clear_reg(Z_R0_scratch);         // Zero indicates a match. Set CC 0 (bcondEqual will be true)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   577
      __ z_br(Z_R14);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   578
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   579
      __ BIND(miss);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   580
      i = 0;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   581
      __ z_lg(Rsubklass,   (i++)*BytesPerWord + frame::z_abi_160_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   582
      __ z_lg(Rsuperklass, (i++)*BytesPerWord + frame::z_abi_160_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   583
      __ z_lg(Rlength,     (i++)*BytesPerWord + frame::z_abi_160_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   584
      __ z_lg(Rarray_ptr,  (i++)*BytesPerWord + frame::z_abi_160_size, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   585
      assert(i*BytesPerWord + frame::z_abi_160_size == frame_size, "check");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   586
      __ pop_frame();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   587
      // return pc is still in R_14
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   588
      __ load_const_optimized(Z_R0_scratch, 1); // One indicates a miss.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   589
      __ z_ltgr(Z_R0_scratch, Z_R0_scratch);    // Set CC 2 (bcondNotEqual will be true).
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   590
      __ z_br(Z_R14);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   591
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   592
    break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   593
    case monitorenter_nofpu_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   594
    case monitorenter_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   595
      { // Z_R1_scratch : object
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   596
        // Z_R13       : lock address (see LIRGenerator::syncTempOpr())
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   597
        __ set_info("monitorenter", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   598
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   599
        int save_fpu_registers = (id == monitorenter_id);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   600
        // Make a frame and preserve the caller's caller-save registers.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   601
        OopMap* oop_map = save_live_registers(sasm, save_fpu_registers);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   602
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   603
        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorenter), Z_R1_scratch, Z_R13);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   604
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   605
        oop_maps = new OopMapSet();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   606
        oop_maps->add_gc_map(call_offset, oop_map);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   607
        restore_live_registers(sasm, save_fpu_registers);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   608
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   609
        __ z_br(Z_R14);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   610
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   611
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   612
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   613
    case monitorexit_nofpu_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   614
    case monitorexit_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   615
      { // Z_R1_scratch : lock address
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   616
        // Note: really a leaf routine but must setup last java sp
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   617
        //   => Use call_RT for now (speed can be improved by
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   618
        //      doing last java sp setup manually).
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   619
        __ set_info("monitorexit", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   620
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   621
        int save_fpu_registers = (id == monitorexit_id);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   622
        // Make a frame and preserve the caller's caller-save registers.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   623
        OopMap* oop_map = save_live_registers(sasm, save_fpu_registers);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   624
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   625
        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorexit), Z_R1_scratch);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   626
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   627
        oop_maps = new OopMapSet();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   628
        oop_maps->add_gc_map(call_offset, oop_map);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   629
        restore_live_registers(sasm, save_fpu_registers);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   630
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   631
        __ z_br(Z_R14);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   632
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   633
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   634
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   635
    case deoptimize_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   636
      { // Args: Z_R1_scratch: trap request
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   637
        __ set_info("deoptimize", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   638
        Register trap_request = Z_R1_scratch;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   639
        OopMap* oop_map = save_live_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   640
        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize), trap_request);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   641
        oop_maps = new OopMapSet();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   642
        oop_maps->add_gc_map(call_offset, oop_map);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   643
        restore_live_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   644
        DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   645
        assert(deopt_blob != NULL, "deoptimization blob must have been created");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   646
        AddressLiteral dest(deopt_blob->unpack_with_reexecution());
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   647
        __ load_const_optimized(Z_R1_scratch, dest);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   648
        __ z_br(Z_R1_scratch);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   649
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   650
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   651
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   652
    case access_field_patching_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   653
      { __ set_info("access_field_patching", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   654
        oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, access_field_patching));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   655
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   656
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   657
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   658
    case load_klass_patching_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   659
      { __ set_info("load_klass_patching", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   660
        // We should set up register map.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   661
        oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_klass_patching));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   662
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   663
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   664
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   665
    case load_mirror_patching_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   666
      { __ set_info("load_mirror_patching", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   667
        oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_mirror_patching));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   668
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   669
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   670
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   671
    case load_appendix_patching_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   672
      { __ set_info("load_appendix_patching", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   673
        oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_appendix_patching));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   674
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   675
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   676
#if 0
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   677
    case dtrace_object_alloc_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   678
      { // rax,: object
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   679
        StubFrame f(sasm, "dtrace_object_alloc", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   680
        // We can't gc here so skip the oopmap but make sure that all
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   681
        // the live registers get saved.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   682
        save_live_registers(sasm, 1);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   683
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   684
        __ NOT_LP64(push(rax)) LP64_ONLY(mov(c_rarg0, rax));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   685
        __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc)));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   686
        NOT_LP64(__ pop(rax));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   687
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   688
        restore_live_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   689
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   690
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   691
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   692
    case fpu2long_stub_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   693
      {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   694
        // rax, and rdx are destroyed, but should be free since the result is returned there
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   695
        // preserve rsi,ecx
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   696
        __ push(rsi);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   697
        __ push(rcx);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   698
        LP64_ONLY(__ push(rdx);)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   699
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   700
        // check for NaN
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   701
        Label return0, do_return, return_min_jlong, do_convert;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   702
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   703
        Address value_high_word(rsp, wordSize + 4);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   704
        Address value_low_word(rsp, wordSize);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   705
        Address result_high_word(rsp, 3*wordSize + 4);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   706
        Address result_low_word(rsp, 3*wordSize);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   707
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   708
        __ subptr(rsp, 32);                    // more than enough on 32bit
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   709
        __ fst_d(value_low_word);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   710
        __ movl(rax, value_high_word);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   711
        __ andl(rax, 0x7ff00000);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   712
        __ cmpl(rax, 0x7ff00000);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   713
        __ jcc(Assembler::notEqual, do_convert);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   714
        __ movl(rax, value_high_word);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   715
        __ andl(rax, 0xfffff);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   716
        __ orl(rax, value_low_word);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   717
        __ jcc(Assembler::notZero, return0);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   718
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   719
        __ bind(do_convert);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   720
        __ fnstcw(Address(rsp, 0));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   721
        __ movzwl(rax, Address(rsp, 0));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   722
        __ orl(rax, 0xc00);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   723
        __ movw(Address(rsp, 2), rax);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   724
        __ fldcw(Address(rsp, 2));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   725
        __ fwait();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   726
        __ fistp_d(result_low_word);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   727
        __ fldcw(Address(rsp, 0));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   728
        __ fwait();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   729
        // This gets the entire long in rax on 64bit
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   730
        __ movptr(rax, result_low_word);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   731
        // testing of high bits
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   732
        __ movl(rdx, result_high_word);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   733
        __ mov(rcx, rax);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   734
        // What the heck is the point of the next instruction???
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   735
        __ xorl(rcx, 0x0);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   736
        __ movl(rsi, 0x80000000);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   737
        __ xorl(rsi, rdx);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   738
        __ orl(rcx, rsi);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   739
        __ jcc(Assembler::notEqual, do_return);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   740
        __ fldz();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   741
        __ fcomp_d(value_low_word);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   742
        __ fnstsw_ax();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   743
        __ testl(rax, 0x4100);  // ZF & CF == 0
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   744
        __ jcc(Assembler::equal, return_min_jlong);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   745
        // return max_jlong
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   746
        __ mov64(rax, CONST64(0x7fffffffffffffff));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   747
        __ jmp(do_return);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   748
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   749
        __ bind(return_min_jlong);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   750
        __ mov64(rax, UCONST64(0x8000000000000000));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   751
        __ jmp(do_return);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   752
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   753
        __ bind(return0);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   754
        __ fpop();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   755
        __ xorptr(rax, rax);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   756
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   757
        __ bind(do_return);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   758
        __ addptr(rsp, 32);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   759
        LP64_ONLY(__ pop(rdx);)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   760
        __ pop(rcx);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   761
        __ pop(rsi);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   762
        __ ret(0);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   763
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   764
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   765
#endif // TODO
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   766
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   767
#if INCLUDE_ALL_GCS
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   768
    case g1_pre_barrier_slow_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   769
      { // Z_R1_scratch: previous value of memory
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   770
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   771
        BarrierSet* bs = Universe::heap()->barrier_set();
49347
edb65305d3ac 8195148: Collapse G1SATBCardTableModRefBS and G1SATBCardTableLoggingModRefBS into a single G1BarrierSet
eosterlund
parents: 49164
diff changeset
   772
        if (bs->kind() != BarrierSet::G1BarrierSet) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   773
          __ should_not_reach_here(FILE_AND_LINE);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   774
          break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   775
        }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   776
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   777
        __ set_info("g1_pre_barrier_slow_id", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   778
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   779
        Register pre_val = Z_R1_scratch;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   780
        Register tmp  = Z_R6; // Must be non-volatile because it is used to save pre_val.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   781
        Register tmp2 = Z_R7;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   782
43449
21041ea7c0fe 8140588: Internal Error: gc/g1/ptrQueue.hpp:126 assert(_index == _sz) failed: invariant: queues are empty when activated
aharlap
parents: 42065
diff changeset
   783
        Label refill, restart, marking_not_active;
49752
93d84f667d12 8201318: Introduce GCThreadLocalData to abstract GC-specific data belonging to a thread
pliden
parents: 49455
diff changeset
   784
        int satb_q_active_byte_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset());
93d84f667d12 8201318: Introduce GCThreadLocalData to abstract GC-specific data belonging to a thread
pliden
parents: 49455
diff changeset
   785
        int satb_q_index_byte_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset());
93d84f667d12 8201318: Introduce GCThreadLocalData to abstract GC-specific data belonging to a thread
pliden
parents: 49455
diff changeset
   786
        int satb_q_buf_byte_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset());
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   787
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   788
        // Save tmp registers (see assertion in G1PreBarrierStub::emit_code()).
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   789
        __ z_stg(tmp,  0*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   790
        __ z_stg(tmp2, 1*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   791
43449
21041ea7c0fe 8140588: Internal Error: gc/g1/ptrQueue.hpp:126 assert(_index == _sz) failed: invariant: queues are empty when activated
aharlap
parents: 42065
diff changeset
   792
        // Is marking still active?
21041ea7c0fe 8140588: Internal Error: gc/g1/ptrQueue.hpp:126 assert(_index == _sz) failed: invariant: queues are empty when activated
aharlap
parents: 42065
diff changeset
   793
        if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
21041ea7c0fe 8140588: Internal Error: gc/g1/ptrQueue.hpp:126 assert(_index == _sz) failed: invariant: queues are empty when activated
aharlap
parents: 42065
diff changeset
   794
          __ load_and_test_int(tmp, Address(Z_thread, satb_q_active_byte_offset));
21041ea7c0fe 8140588: Internal Error: gc/g1/ptrQueue.hpp:126 assert(_index == _sz) failed: invariant: queues are empty when activated
aharlap
parents: 42065
diff changeset
   795
        } else {
21041ea7c0fe 8140588: Internal Error: gc/g1/ptrQueue.hpp:126 assert(_index == _sz) failed: invariant: queues are empty when activated
aharlap
parents: 42065
diff changeset
   796
          assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
21041ea7c0fe 8140588: Internal Error: gc/g1/ptrQueue.hpp:126 assert(_index == _sz) failed: invariant: queues are empty when activated
aharlap
parents: 42065
diff changeset
   797
          __ load_and_test_byte(tmp, Address(Z_thread, satb_q_active_byte_offset));
21041ea7c0fe 8140588: Internal Error: gc/g1/ptrQueue.hpp:126 assert(_index == _sz) failed: invariant: queues are empty when activated
aharlap
parents: 42065
diff changeset
   798
        }
21041ea7c0fe 8140588: Internal Error: gc/g1/ptrQueue.hpp:126 assert(_index == _sz) failed: invariant: queues are empty when activated
aharlap
parents: 42065
diff changeset
   799
        __ z_bre(marking_not_active); // Activity indicator is zero, so there is no marking going on currently.
21041ea7c0fe 8140588: Internal Error: gc/g1/ptrQueue.hpp:126 assert(_index == _sz) failed: invariant: queues are empty when activated
aharlap
parents: 42065
diff changeset
   800
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   801
        __ bind(restart);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   802
        // Load the index into the SATB buffer. SATBMarkQueue::_index is a
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   803
        // size_t so ld_ptr is appropriate.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   804
        __ z_ltg(tmp, satb_q_index_byte_offset, Z_R0, Z_thread);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   805
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   806
        // index == 0?
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   807
        __ z_brz(refill);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   808
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   809
        __ z_lg(tmp2, satb_q_buf_byte_offset, Z_thread);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   810
        __ add2reg(tmp, -oopSize);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   811
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   812
        __ z_stg(pre_val, 0, tmp, tmp2); // [_buf + index] := <address_of_card>
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   813
        __ z_stg(tmp, satb_q_index_byte_offset, Z_thread);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   814
43449
21041ea7c0fe 8140588: Internal Error: gc/g1/ptrQueue.hpp:126 assert(_index == _sz) failed: invariant: queues are empty when activated
aharlap
parents: 42065
diff changeset
   815
        __ bind(marking_not_active);
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   816
        // Restore tmp registers (see assertion in G1PreBarrierStub::emit_code()).
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   817
        __ z_lg(tmp,  0*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   818
        __ z_lg(tmp2, 1*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   819
        __ z_br(Z_R14);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   820
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   821
        __ bind(refill);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   822
        save_volatile_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   823
        __ z_lgr(tmp, pre_val); // save pre_val
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   824
        __ call_VM_leaf(CAST_FROM_FN_PTR(address, SATBMarkQueueSet::handle_zero_index_for_thread),
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   825
                        Z_thread);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   826
        __ z_lgr(pre_val, tmp); // restore pre_val
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   827
        restore_volatile_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   828
        __ z_bru(restart);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   829
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   830
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   831
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   832
    case g1_post_barrier_slow_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   833
      { // Z_R1_scratch: oop address, address of updated memory slot
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   834
        BarrierSet* bs = Universe::heap()->barrier_set();
49347
edb65305d3ac 8195148: Collapse G1SATBCardTableModRefBS and G1SATBCardTableLoggingModRefBS into a single G1BarrierSet
eosterlund
parents: 49164
diff changeset
   835
        if (bs->kind() != BarrierSet::G1BarrierSet) {
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   836
          __ should_not_reach_here(FILE_AND_LINE);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   837
          break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   838
        }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   839
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   840
        __ set_info("g1_post_barrier_slow_id", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   841
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   842
        Register addr_oop  = Z_R1_scratch;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   843
        Register addr_card = Z_R1_scratch;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   844
        Register r1        = Z_R6; // Must be saved/restored.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   845
        Register r2        = Z_R7; // Must be saved/restored.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   846
        Register cardtable = r1;   // Must be non-volatile, because it is used to save addr_card.
49164
7e958a8ebcd3 8195142: Refactor out card table from CardTableModRefBS to flatten the BarrierSet hierarchy
eosterlund
parents: 49010
diff changeset
   847
        jbyte* byte_map_base = ci_card_table_address();
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   848
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   849
        // Save registers used below (see assertion in G1PreBarrierStub::emit_code()).
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   850
        __ z_stg(r1, 0*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   851
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   852
        Label not_already_dirty, restart, refill, young_card;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   853
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   854
        // Calculate address of card corresponding to the updated oop slot.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   855
        AddressLiteral rs(byte_map_base);
49164
7e958a8ebcd3 8195142: Refactor out card table from CardTableModRefBS to flatten the BarrierSet hierarchy
eosterlund
parents: 49010
diff changeset
   856
        __ z_srlg(addr_card, addr_oop, CardTable::card_shift);
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   857
        addr_oop = noreg; // dead now
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   858
        __ load_const_optimized(cardtable, rs); // cardtable := <card table base>
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   859
        __ z_agr(addr_card, cardtable); // addr_card := addr_oop>>card_shift + cardtable
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   860
49164
7e958a8ebcd3 8195142: Refactor out card table from CardTableModRefBS to flatten the BarrierSet hierarchy
eosterlund
parents: 49010
diff changeset
   861
        __ z_cli(0, addr_card, (int)G1CardTable::g1_young_card_val());
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   862
        __ z_bre(young_card);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   863
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   864
        __ z_sync(); // Required to support concurrent cleaning.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   865
49164
7e958a8ebcd3 8195142: Refactor out card table from CardTableModRefBS to flatten the BarrierSet hierarchy
eosterlund
parents: 49010
diff changeset
   866
        __ z_cli(0, addr_card, (int)CardTable::dirty_card_val());
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   867
        __ z_brne(not_already_dirty);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   868
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   869
        __ bind(young_card);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   870
        // We didn't take the branch, so we're already dirty: restore
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   871
        // used registers and return.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   872
        __ z_lg(r1, 0*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   873
        __ z_br(Z_R14);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   874
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   875
        // Not dirty.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   876
        __ bind(not_already_dirty);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   877
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   878
        // First, dirty it: [addr_card] := 0
49164
7e958a8ebcd3 8195142: Refactor out card table from CardTableModRefBS to flatten the BarrierSet hierarchy
eosterlund
parents: 49010
diff changeset
   879
        __ z_mvi(0, addr_card, CardTable::dirty_card_val());
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   880
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   881
        Register idx = cardtable; // Must be non-volatile, because it is used to save addr_card.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   882
        Register buf = r2;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   883
        cardtable = noreg; // now dead
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   884
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   885
        // Save registers used below (see assertion in G1PreBarrierStub::emit_code()).
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   886
        __ z_stg(r2, 1*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   887
49752
93d84f667d12 8201318: Introduce GCThreadLocalData to abstract GC-specific data belonging to a thread
pliden
parents: 49455
diff changeset
   888
        ByteSize dirty_card_q_index_byte_offset = G1ThreadLocalData::dirty_card_queue_index_offset();
93d84f667d12 8201318: Introduce GCThreadLocalData to abstract GC-specific data belonging to a thread
pliden
parents: 49455
diff changeset
   889
        ByteSize dirty_card_q_buf_byte_offset = G1ThreadLocalData::dirty_card_queue_buffer_offset();
42065
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   890
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   891
        __ bind(restart);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   892
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   893
        // Get the index into the update buffer. DirtyCardQueue::_index is
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   894
        // a size_t so z_ltg is appropriate here.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   895
        __ z_ltg(idx, Address(Z_thread, dirty_card_q_index_byte_offset));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   896
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   897
        // index == 0?
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   898
        __ z_brz(refill);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   899
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   900
        __ z_lg(buf, Address(Z_thread, dirty_card_q_buf_byte_offset));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   901
        __ add2reg(idx, -oopSize);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   902
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   903
        __ z_stg(addr_card, 0, idx, buf); // [_buf + index] := <address_of_card>
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   904
        __ z_stg(idx, Address(Z_thread, dirty_card_q_index_byte_offset));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   905
        // Restore killed registers and return.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   906
        __ z_lg(r1, 0*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   907
        __ z_lg(r2, 1*BytesPerWord + FrameMap::first_available_sp_in_frame, Z_SP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   908
        __ z_br(Z_R14);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   909
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   910
        __ bind(refill);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   911
        save_volatile_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   912
        __ z_lgr(idx, addr_card); // Save addr_card, tmp3 must be non-volatile.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   913
        __ call_VM_leaf(CAST_FROM_FN_PTR(address, DirtyCardQueueSet::handle_zero_index_for_thread),
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   914
                                         Z_thread);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   915
        __ z_lgr(addr_card, idx);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   916
        restore_volatile_registers(sasm); // Restore addr_card.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   917
        __ z_bru(restart);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   918
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   919
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   920
#endif // INCLUDE_ALL_GCS
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   921
    case predicate_failed_trap_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   922
      {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   923
        __ set_info("predicate_failed_trap", dont_gc_arguments);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   924
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   925
        OopMap* map = save_live_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   926
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   927
        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   928
        oop_maps = new OopMapSet();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   929
        oop_maps->add_gc_map(call_offset, map);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   930
        restore_live_registers(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   931
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   932
        DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   933
        assert(deopt_blob != NULL, "deoptimization blob must have been created");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   934
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   935
        __ load_const_optimized(Z_R1_scratch, deopt_blob->unpack_with_reexecution());
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   936
        __ z_br(Z_R1_scratch);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   937
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   938
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   939
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   940
    default:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   941
      {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   942
        __ should_not_reach_here(FILE_AND_LINE, id);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   943
      }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   944
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   945
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   946
  return oop_maps;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   947
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   948
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   949
OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler *sasm) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   950
  __ block_comment("generate_handle_exception");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   951
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   952
  // incoming parameters: Z_EXC_OOP, Z_EXC_PC
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   953
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   954
  // Save registers if required.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   955
  OopMapSet* oop_maps = new OopMapSet();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   956
  OopMap* oop_map = NULL;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   957
  Register reg_fp = Z_R1_scratch;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   958
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   959
  switch (id) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   960
    case forward_exception_id: {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   961
      // We're handling an exception in the context of a compiled frame.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   962
      // The registers have been saved in the standard places. Perform
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   963
      // an exception lookup in the caller and dispatch to the handler
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   964
      // if found. Otherwise unwind and dispatch to the callers
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   965
      // exception handler.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   966
      oop_map = generate_oop_map(sasm);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   967
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   968
      // Load and clear pending exception oop into.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   969
      __ z_lg(Z_EXC_OOP, Address(Z_thread, Thread::pending_exception_offset()));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   970
      __ clear_mem(Address(Z_thread, Thread::pending_exception_offset()), 8);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   971
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   972
      // Different stubs forward their exceptions; they should all have similar frame layouts
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   973
      // (a) to find their return address (b) for a correct oop_map generated above.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   974
      assert(RegisterSaver::live_reg_frame_size(RegisterSaver::all_registers) ==
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   975
             RegisterSaver::live_reg_frame_size(RegisterSaver::all_registers_except_r2), "requirement");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   976
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   977
      // Load issuing PC (the return address for this stub).
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   978
      const int frame_size_in_bytes = sasm->frame_size() * VMRegImpl::slots_per_word * VMRegImpl::stack_slot_size;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   979
      __ z_lg(Z_EXC_PC, Address(Z_SP, frame_size_in_bytes + _z_abi16(return_pc)));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   980
      DEBUG_ONLY(__ z_lay(reg_fp, Address(Z_SP, frame_size_in_bytes));)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   981
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   982
      // Make sure that the vm_results are cleared (may be unnecessary).
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   983
      __ clear_mem(Address(Z_thread, JavaThread::vm_result_offset()),   sizeof(oop));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   984
      __ clear_mem(Address(Z_thread, JavaThread::vm_result_2_offset()), sizeof(Metadata*));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   985
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   986
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   987
    case handle_exception_nofpu_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   988
    case handle_exception_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   989
      // At this point all registers MAY be live.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   990
      DEBUG_ONLY(__ z_lgr(reg_fp, Z_SP);)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   991
      oop_map = save_live_registers(sasm, id != handle_exception_nofpu_id, Z_EXC_PC);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   992
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   993
    case handle_exception_from_callee_id: {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   994
      // At this point all registers except Z_EXC_OOP and Z_EXC_PC are dead.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   995
      DEBUG_ONLY(__ z_lgr(reg_fp, Z_SP);)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   996
      __ save_return_pc(Z_EXC_PC);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   997
      const int frame_size_in_bytes = __ push_frame_abi160(0);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   998
      oop_map = new OopMap(frame_size_in_bytes / VMRegImpl::stack_slot_size, 0);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
   999
      sasm->set_frame_size(frame_size_in_bytes / BytesPerWord);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1000
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1001
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1002
    default:  ShouldNotReachHere();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1003
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1004
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1005
  // Verify that only Z_EXC_OOP, and Z_EXC_PC are valid at this time.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1006
  __ invalidate_registers(Z_EXC_OOP, Z_EXC_PC, reg_fp);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1007
  // Verify that Z_EXC_OOP, contains a valid exception.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1008
  __ verify_not_null_oop(Z_EXC_OOP);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1009
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1010
  // Check that fields in JavaThread for exception oop and issuing pc
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1011
  // are empty before writing to them.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1012
  __ asm_assert_mem8_is_zero(in_bytes(JavaThread::exception_oop_offset()), Z_thread, "exception oop already set : " FILE_AND_LINE, 0);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1013
  __ asm_assert_mem8_is_zero(in_bytes(JavaThread::exception_pc_offset()), Z_thread, "exception pc already set : " FILE_AND_LINE, 0);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1014
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1015
  // Save exception oop and issuing pc into JavaThread.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1016
  // (Exception handler will load it from here.)
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1017
  __ z_stg(Z_EXC_OOP, Address(Z_thread, JavaThread::exception_oop_offset()));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1018
  __ z_stg(Z_EXC_PC, Address(Z_thread, JavaThread::exception_pc_offset()));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1019
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1020
#ifdef ASSERT
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1021
  { NearLabel ok;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1022
    __ z_cg(Z_EXC_PC, Address(reg_fp, _z_abi16(return_pc)));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1023
    __ branch_optimized(Assembler::bcondEqual, ok);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1024
    __ stop("use throwing pc as return address (has bci & oop map)");
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1025
    __ bind(ok);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1026
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1027
#endif
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1028
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1029
  // Compute the exception handler.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1030
  // The exception oop and the throwing pc are read from the fields in JavaThread.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1031
  int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1032
  oop_maps->add_gc_map(call_offset, oop_map);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1033
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1034
  // Z_RET(Z_R2): handler address
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1035
  //   will be the deopt blob if nmethod was deoptimized while we looked up
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1036
  //   handler regardless of whether handler existed in the nmethod.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1037
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1038
  // Only Z_R2, is valid at this time, all other registers have been destroyed by the runtime call.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1039
  __ invalidate_registers(Z_R2);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1040
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1041
  switch(id) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1042
    case forward_exception_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1043
    case handle_exception_nofpu_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1044
    case handle_exception_id:
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1045
      // Restore the registers that were saved at the beginning.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1046
      __ z_lgr(Z_R1_scratch, Z_R2);   // Restoring live registers kills Z_R2.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1047
      restore_live_registers(sasm, id != handle_exception_nofpu_id);  // Pops as well the frame.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1048
      __ z_br(Z_R1_scratch);
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1049
      break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1050
    case handle_exception_from_callee_id: {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1051
      __ pop_frame();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1052
      __ z_br(Z_R2); // Jump to exception handler.
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1053
    }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1054
    break;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1055
    default:  ShouldNotReachHere();
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1056
  }
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1057
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1058
  return oop_maps;
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1059
}
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1060
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1061
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1062
#undef __
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1063
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1064
const char *Runtime1::pd_name_for_address(address entry) {
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1065
  return "<unknown function>";
6032b31e3719 8167673: [s390] The s390 port.
goetz
parents:
diff changeset
  1066
}