compiledIC_sparc.cpp revision 11680:c8f294158cfc
1235537Sgber/*
2235537Sgber * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3235537Sgber * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4235537Sgber *
5235537Sgber * This code is free software; you can redistribute it and/or modify it
6235537Sgber * under the terms of the GNU General Public License version 2 only, as
7235537Sgber * published by the Free Software Foundation.
8235537Sgber *
9235537Sgber * This code is distributed in the hope that it will be useful, but WITHOUT
10235537Sgber * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11235537Sgber * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12235537Sgber * version 2 for more details (a copy is included in the LICENSE file that
13235537Sgber * accompanied this code).
14235537Sgber *
15235537Sgber * You should have received a copy of the GNU General Public License version
16235537Sgber * 2 along with this work; if not, write to the Free Software Foundation,
17235537Sgber * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18235537Sgber *
19235537Sgber * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20235537Sgber * or visit www.oracle.com if you need additional information or have any
21235537Sgber * questions.
22235537Sgber *
23235537Sgber */
24235537Sgber
25235537Sgber#include "precompiled.hpp"
26235537Sgber#include "asm/macroAssembler.inline.hpp"
27235537Sgber#include "code/compiledIC.hpp"
28235537Sgber#include "code/icBuffer.hpp"
29235537Sgber#include "code/nmethod.hpp"
30235537Sgber#include "memory/resourceArea.hpp"
31235537Sgber#include "runtime/mutexLocker.hpp"
32235537Sgber#include "runtime/safepoint.hpp"
33235537Sgber#ifdef COMPILER2
34235537Sgber#include "opto/matcher.hpp"
35235537Sgber#endif
36235537Sgber
37235537Sgber// ----------------------------------------------------------------------------
38235537Sgber
39235537Sgber#define __ _masm.
40235537Sgberaddress CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf, address mark) {
41235537Sgber  // Stub is fixed up when the corresponding call is converted from calling
42235537Sgber  // compiled code to calling interpreted code.
43235537Sgber  // set (empty), G5
44235537Sgber  // jmp -1
45235537Sgber
46235537Sgber  if (mark == NULL) {
47235537Sgber    mark = cbuf.insts_mark();  // Get mark within main instrs section.
48235537Sgber  }
49235537Sgber
50235537Sgber  MacroAssembler _masm(&cbuf);
51
52  address base = __ start_a_stub(to_interp_stub_size());
53  if (base == NULL) {
54    return NULL;  // CodeBuffer::expand failed.
55  }
56
57  // Static stub relocation stores the instruction address of the call.
58  __ relocate(static_stub_Relocation::spec(mark));
59
60  __ set_metadata(NULL, as_Register(Matcher::inline_cache_reg_encode()));
61
62  __ set_inst_mark();
63  AddressLiteral addrlit(-1);
64  __ JUMP(addrlit, G3, 0);
65
66  __ delayed()->nop();
67
68  assert(__ pc() - base <= to_interp_stub_size(), "wrong stub size");
69
70  // Update current stubs pointer and restore code_end.
71  __ end_a_stub();
72  return base;
73}
74#undef __
75
76int CompiledStaticCall::to_interp_stub_size() {
77  // This doesn't need to be accurate but it must be larger or equal to
78  // the real size of the stub.
79  return (NativeMovConstReg::instruction_size +  // sethi/setlo;
80          NativeJump::instruction_size); // sethi; jmp; nop
81}
82
83// Relocation entries for call stub, compiled java to interpreter.
84int CompiledStaticCall::reloc_to_interp_stub() {
85  return 10;  // 4 in emit_java_to_interp + 1 in Java_Static_Call
86}
87
88void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry) {
89  address stub = find_stub();
90  guarantee(stub != NULL, "stub not found");
91
92  if (TraceICs) {
93    ResourceMark rm;
94    tty->print_cr("CompiledStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
95                  p2i(instruction_address()),
96                  callee->name_and_sig_as_C_string());
97  }
98
99  // Creation also verifies the object.
100  NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
101  NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
102
103#ifdef ASSERT
104  // read the value once
105  intptr_t data = method_holder->data();
106  address destination = jump->jump_destination();
107  assert(data == 0 || data == (intptr_t)callee(),
108         "a) MT-unsafe modification of inline cache");
109  assert(destination == (address)-1 || destination == entry,
110         "b) MT-unsafe modification of inline cache");
111#endif
112
113  // Update stub.
114  method_holder->set_data((intptr_t)callee());
115  jump->set_jump_destination(entry);
116
117  // Update jump to call.
118  set_destination_mt_safe(stub);
119}
120
121void CompiledStaticCall::set_stub_to_clean(static_stub_Relocation* static_stub) {
122  assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "mt unsafe call");
123  // Reset stub.
124  address stub = static_stub->addr();
125  assert(stub != NULL, "stub not found");
126  // Creation also verifies the object.
127  NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
128  NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
129  method_holder->set_data(0);
130  jump->set_jump_destination((address)-1);
131}
132
133//-----------------------------------------------------------------------------
134// Non-product mode code
135#ifndef PRODUCT
136
137void CompiledStaticCall::verify() {
138  // Verify call.
139  NativeCall::verify();
140  if (os::is_MP()) {
141    verify_alignment();
142  }
143
144  // Verify stub.
145  address stub = find_stub();
146  assert(stub != NULL, "no stub found for static call");
147  // Creation also verifies the object.
148  NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
149  NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
150
151  // Verify state.
152  assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted(), "sanity check");
153}
154
155#endif // !PRODUCT
156