Tue, 26 Jul 2016 17:06:17 +0800
Add multiply word to GPR instruction (mul) in MIPS assembler.
1 /*
2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
26 #include "precompiled.hpp"
27 #include "asm/macroAssembler.inline.hpp"
28 #include "code/compiledIC.hpp"
29 #include "code/icBuffer.hpp"
30 #include "code/nmethod.hpp"
31 #include "memory/resourceArea.hpp"
32 #include "runtime/mutexLocker.hpp"
33 #include "runtime/safepoint.hpp"
35 // Release the CompiledICHolder* associated with this call site is there is one.
36 void CompiledIC::cleanup_call_site(virtual_call_Relocation* call_site) {
37 // This call site might have become stale so inspect it carefully.
38 NativeCall* call = nativeCall_at(call_site->addr());
39 if (is_icholder_entry(call->destination())) {
40 NativeMovConstReg* value = nativeMovConstReg_at(call_site->cached_value());
41 InlineCacheBuffer::queue_for_release((CompiledICHolder*)value->data());
42 }
43 }
45 bool CompiledIC::is_icholder_call_site(virtual_call_Relocation* call_site) {
46 // This call site might have become stale so inspect it carefully.
47 NativeCall* call = nativeCall_at(call_site->addr());
48 return is_icholder_entry(call->destination());
49 }
51 //-----------------------------------------------------------------------------
52 // High-level access to an inline cache. Guaranteed to be MT-safe.
54 CompiledIC::CompiledIC(nmethod* nm, NativeCall* call)
55 : _ic_call(call)
56 {
57 address ic_call = call->instruction_address();
59 assert(ic_call != NULL, "ic_call address must be set");
60 assert(nm != NULL, "must pass nmethod");
61 assert(nm->contains(ic_call), "must be in nmethod");
63 // Search for the ic_call at the given address.
64 RelocIterator iter(nm, ic_call, ic_call+1);
65 bool ret = iter.next();
66 assert(ret == true, "relocInfo must exist at this address");
67 assert(iter.addr() == ic_call, "must find ic_call");
68 if (iter.type() == relocInfo::virtual_call_type) {
69 virtual_call_Relocation* r = iter.virtual_call_reloc();
70 _is_optimized = false;
71 _value = nativeMovConstReg_at(r->cached_value());
72 } else {
73 assert(iter.type() == relocInfo::opt_virtual_call_type, "must be a virtual call");
74 _is_optimized = true;
75 _value = NULL;
76 }
77 }
79 // ----------------------------------------------------------------------------
81 #define __ _masm.
82 void CompiledStaticCall::emit_to_interp_stub(CodeBuffer &cbuf) {
84 address mark = cbuf.insts_mark(); // get mark within main instrs section
86 // Note that the code buffer's insts_mark is always relative to insts.
87 // That's why we must use the macroassembler to generate a stub.
88 MacroAssembler _masm(&cbuf);
90 address base =
91 __ start_a_stub(Compile::MAX_stubs_size);
92 if (base == NULL) return; // CodeBuffer::expand failed
93 // static stub relocation stores the instruction address of the call
95 __ relocate(static_stub_Relocation::spec(mark), 0);
97 /* 2012/10/29 Jin: Rmethod contains methodOop, it should be relocated for GC */
98 /*
99 int oop_index = __ oop_recorder()->allocate_index(NULL);
100 RelocationHolder rspec = oop_Relocation::spec(oop_index);
101 __ relocate(rspec);
102 */
104 // static stub relocation also tags the methodOop in the code-stream.
105 __ li48(S3, (long)0);
106 // This is recognized as unresolved by relocs/nativeInst/ic code
108 __ relocate(relocInfo::runtime_call_type);
110 cbuf.set_insts_mark();
111 address call_pc = (address)-1;
112 __ li48(AT, (long)call_pc);
113 __ jr(AT);
114 __ nop();
115 __ align(16);
116 __ end_a_stub();
117 // Update current stubs pointer and restore code_end.
118 }
119 #undef __
121 int CompiledStaticCall::to_interp_stub_size() {
122 int size = 4 * 4 + NativeCall::instruction_size; // sizeof(li48) + NativeCall::instruction_size
123 return round_to(size, 16);
124 }
126 // Relocation entries for call stub, compiled java to interpreter.
127 int CompiledStaticCall::reloc_to_interp_stub() {
128 return 16;
129 }
131 void CompiledStaticCall::set_to_interpreted(methodHandle callee, address entry) {
132 address stub = find_stub();
133 guarantee(stub != NULL, "stub not found");
135 if (TraceICs) {
136 ResourceMark rm;
137 tty->print_cr("CompiledStaticCall@" INTPTR_FORMAT ": set_to_interpreted %s",
138 instruction_address(),
139 callee->name_and_sig_as_C_string());
140 }
142 // Creation also verifies the object.
143 NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
144 #ifndef MIPS64
145 NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
146 #else
147 NativeGeneralJump* jump = nativeGeneralJump_at(method_holder->next_instruction_address());
148 #endif
150 assert(method_holder->data() == 0 || method_holder->data() == (intptr_t)callee(),
151 "a) MT-unsafe modification of inline cache");
152 assert(jump->jump_destination() == (address)-1 || jump->jump_destination() == entry,
153 "b) MT-unsafe modification of inline cache");
155 // Update stub.
156 method_holder->set_data((intptr_t)callee());
157 jump->set_jump_destination(entry);
159 // Update jump to call.
160 set_destination_mt_safe(stub);
161 }
163 void CompiledStaticCall::set_stub_to_clean(static_stub_Relocation* static_stub) {
164 assert (CompiledIC_lock->is_locked() || SafepointSynchronize::is_at_safepoint(), "mt unsafe call");
165 // Reset stub.
166 address stub = static_stub->addr();
167 assert(stub != NULL, "stub not found");
168 // Creation also verifies the object.
169 NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
170 #ifndef MIPS64
171 NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
172 #else
173 NativeGeneralJump* jump = nativeGeneralJump_at(method_holder->next_instruction_address());
174 #endif
175 method_holder->set_data(0);
176 jump->set_jump_destination((address)-1);
177 }
179 //-----------------------------------------------------------------------------
180 // Non-product mode code
181 #ifndef PRODUCT
183 void CompiledStaticCall::verify() {
184 // Verify call.
185 NativeCall::verify();
186 if (os::is_MP()) {
187 verify_alignment();
188 }
190 // Verify stub.
191 address stub = find_stub();
192 assert(stub != NULL, "no stub found for static call");
193 // Creation also verifies the object.
194 NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
195 #ifndef MIPS64
196 NativeJump* jump = nativeJump_at(method_holder->next_instruction_address());
197 #else
198 NativeGeneralJump* jump = nativeGeneralJump_at(method_holder->next_instruction_address());
199 #endif
202 // Verify state.
203 assert(is_clean() || is_call_to_compiled() || is_call_to_interpreted(), "sanity check");
204 }
206 #endif // !PRODUCT