1 /*
  2  * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #include "precompiled.hpp"
 26 
 27 #include "classfile/bytecodeAssembler.hpp"
 28 #include "interpreter/bytecodes.hpp"
 29 #include "memory/oopFactory.hpp"
 30 #include "oops/constantPool.hpp"
 31 #include "runtime/handles.inline.hpp"
 32 #include "utilities/bytes.hpp"
 33 
 34 u2 BytecodeConstantPool::find_or_add(BytecodeCPEntry const& bcpe) {
 35 
 36   u2 index = _entries.length();
 37   bool created = false;
 38   u2* probe = _indices.put_if_absent(bcpe, index, &created);
 39   if (created) {
 40     _entries.append(bcpe);
 41   } else {
 42     index = *probe;
 43   }
 44   return index + _orig->length();
 45 }
 46 
 47 ConstantPool* BytecodeConstantPool::create_constant_pool(TRAPS) const {
 48   if (_entries.length() == 0) {
 49     return _orig;
 50   }
 51 
 52   ConstantPool* cp = ConstantPool::allocate(
 53       _orig->pool_holder()->class_loader_data(),
 54       _orig->length() + _entries.length(), CHECK_NULL);
 55 
 56   cp->set_pool_holder(_orig->pool_holder());
 57   constantPoolHandle cp_h(THREAD, cp);
 58   _orig->copy_cp_to(1, _orig->length() - 1, cp_h, 1, CHECK_NULL);
 59 
 60   // Preserve dynamic constant information from the original pool
 61   cp->copy_fields(_orig);
 62 
 63   for (int i = 0; i < _entries.length(); ++i) {
 64     BytecodeCPEntry entry = _entries.at(i);
 65     int idx = i + _orig->length();
 66     switch (entry._tag) {
 67       case BytecodeCPEntry::UTF8:
 68         entry._u.utf8->increment_refcount();
 69         cp->symbol_at_put(idx, entry._u.utf8);
 70         break;
 71       case BytecodeCPEntry::KLASS:
 72         cp->klass_index_at_put(
 73             idx, entry._u.klass);
 74         break;
 75       case BytecodeCPEntry::STRING:
 76         cp->unresolved_string_at_put(
 77             idx, cp->symbol_at(entry._u.string));
 78         break;
 79       case BytecodeCPEntry::NAME_AND_TYPE:
 80         cp->name_and_type_at_put(idx,
 81             entry._u.name_and_type.name_index,
 82             entry._u.name_and_type.type_index);
 83         break;
 84       case BytecodeCPEntry::METHODREF:
 85         cp->method_at_put(idx,
 86             entry._u.methodref.class_index,
 87             entry._u.methodref.name_and_type_index);
 88         break;
 89       default:
 90         ShouldNotReachHere();
 91     }
 92   }
 93 
 94   cp->initialize_unresolved_klasses(_orig->pool_holder()->class_loader_data(),
 95                                     CHECK_NULL);
 96   return cp;
 97 }
 98 
 99 void BytecodeAssembler::append(u1 imm_u1) {
100   _code->append(imm_u1);
101 }
102 
103 void BytecodeAssembler::append(u2 imm_u2) {
104   _code->append(0);
105   _code->append(0);
106   Bytes::put_Java_u2(_code->adr_at(_code->length() - 2), imm_u2);
107 }
108 
109 void BytecodeAssembler::append(u4 imm_u4) {
110   _code->append(0);
111   _code->append(0);
112   _code->append(0);
113   _code->append(0);
114   Bytes::put_Java_u4(_code->adr_at(_code->length() - 4), imm_u4);
115 }
116 
117 void BytecodeAssembler::xload(u4 index, u1 onebyteop, u1 twobyteop) {
118   if (index < 4) {
119     _code->append(onebyteop + index);
120   } else {
121     _code->append(twobyteop);
122     _code->append((u2)index);
123   }
124 }
125 
126 void BytecodeAssembler::dup() {
127   _code->append(Bytecodes::_dup);
128 }
129 
130 void BytecodeAssembler::_new(Symbol* sym) {
131   u2 cpool_index = _cp->klass(sym);
132   _code->append(Bytecodes::_new);
133   append(cpool_index);
134 }
135 
136 void BytecodeAssembler::load_string(Symbol* sym) {
137   u2 cpool_index = _cp->string(sym);
138   if (cpool_index < 0x100) {
139     ldc(cpool_index);
140   } else {
141     ldc_w(cpool_index);
142   }
143 }
144 
145 void BytecodeAssembler::ldc(u1 index) {
146   _code->append(Bytecodes::_ldc);
147   append(index);
148 }
149 
150 void BytecodeAssembler::ldc_w(u2 index) {
151   _code->append(Bytecodes::_ldc_w);
152   append(index);
153 }
154 
155 void BytecodeAssembler::athrow() {
156   _code->append(Bytecodes::_athrow);
157 }
158 
159 void BytecodeAssembler::iload(u4 index) {
160   xload(index, Bytecodes::_iload_0, Bytecodes::_iload);
161 }
162 
163 void BytecodeAssembler::lload(u4 index) {
164   xload(index, Bytecodes::_lload_0, Bytecodes::_lload);
165 }
166 
167 void BytecodeAssembler::fload(u4 index) {
168   xload(index, Bytecodes::_fload_0, Bytecodes::_fload);
169 }
170 
171 void BytecodeAssembler::dload(u4 index) {
172   xload(index, Bytecodes::_dload_0, Bytecodes::_dload);
173 }
174 
175 void BytecodeAssembler::aload(u4 index) {
176   xload(index, Bytecodes::_aload_0, Bytecodes::_aload);
177 }
178 
179 void BytecodeAssembler::load(BasicType bt, u4 index) {
180   switch (bt) {
181     case T_BOOLEAN:
182     case T_CHAR:
183     case T_BYTE:
184     case T_SHORT:
185     case T_INT:     iload(index); break;
186     case T_FLOAT:   fload(index); break;
187     case T_DOUBLE:  dload(index); break;
188     case T_LONG:    lload(index); break;
189     default:
190       if (is_reference_type(bt)) {
191                     aload(index);
192                     break;
193       }
194       ShouldNotReachHere();
195   }
196 }
197 
198 void BytecodeAssembler::checkcast(Symbol* sym) {
199   u2 cpool_index = _cp->klass(sym);
200   _code->append(Bytecodes::_checkcast);
201   append(cpool_index);
202 }
203 
204 void BytecodeAssembler::invokespecial(Method* method) {
205   invokespecial(method->klass_name(), method->name(), method->signature());
206 }
207 
208 void BytecodeAssembler::invokespecial(Symbol* klss, Symbol* name, Symbol* sig) {
209   u2 methodref_index = _cp->methodref(klss, name, sig);
210   _code->append(Bytecodes::_invokespecial);
211   append(methodref_index);
212 }
213 
214 void BytecodeAssembler::invokevirtual(Method* method) {
215   invokevirtual(method->klass_name(), method->name(), method->signature());
216 }
217 
218 void BytecodeAssembler::invokevirtual(Symbol* klss, Symbol* name, Symbol* sig) {
219   u2 methodref_index = _cp->methodref(klss, name, sig);
220   _code->append(Bytecodes::_invokevirtual);
221   append(methodref_index);
222 }
223 
224 void BytecodeAssembler::ireturn() {
225   _code->append(Bytecodes::_ireturn);
226 }
227 
228 void BytecodeAssembler::lreturn() {
229   _code->append(Bytecodes::_lreturn);
230 }
231 
232 void BytecodeAssembler::freturn() {
233   _code->append(Bytecodes::_freturn);
234 }
235 
236 void BytecodeAssembler::dreturn() {
237   _code->append(Bytecodes::_dreturn);
238 }
239 
240 void BytecodeAssembler::areturn() {
241   _code->append(Bytecodes::_areturn);
242 }
243 
244 void BytecodeAssembler::_return() {
245   _code->append(Bytecodes::_return);
246 }
247 
248 void BytecodeAssembler::_return(BasicType bt) {
249   switch (bt) {
250     case T_BOOLEAN:
251     case T_CHAR:
252     case T_BYTE:
253     case T_SHORT:
254     case T_INT:     ireturn(); break;
255     case T_FLOAT:   freturn(); break;
256     case T_DOUBLE:  dreturn(); break;
257     case T_LONG:    lreturn(); break;
258     case T_VOID:    _return(); break;
259     default:
260       if (is_reference_type(bt)) {
261                     areturn();
262                     break;
263       }
264       ShouldNotReachHere();
265   }
266 }