src/share/vm/classfile/bytecodeAssembler.hpp

Thu, 22 May 2014 15:52:41 -0400

author
drchase
date
Thu, 22 May 2014 15:52:41 -0400
changeset 6680
78bbf4d43a14
parent 0
f90c822e73f8
permissions
-rw-r--r--

8037816: Fix for 8036122 breaks build with Xcode5/clang
8043029: Change 8037816 breaks HS build with older GCC versions which don't support diagnostic pragmas
8043164: Format warning in traceStream.hpp
Summary: Backport of main fix + two corrections, enables clang compilation, turns on format attributes, corrects/mutes warnings
Reviewed-by: kvn, coleenp, iveresov, twisti

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #ifndef SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP
aoqi@0 26 #define SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP
aoqi@0 27
aoqi@0 28 #include "memory/allocation.hpp"
aoqi@0 29 #include "oops/method.hpp"
aoqi@0 30 #include "oops/symbol.hpp"
aoqi@0 31 #include "utilities/globalDefinitions.hpp"
aoqi@0 32 #include "utilities/growableArray.hpp"
aoqi@0 33 #include "utilities/resourceHash.hpp"
aoqi@0 34
aoqi@0 35
aoqi@0 36 /**
aoqi@0 37 * Bytecode Assembler
aoqi@0 38 *
aoqi@0 39 * These classes are used to synthesize code for creating new methods from
aoqi@0 40 * within the VM. This is only a partial implementation of an assembler;
aoqi@0 41 * only the bytecodes that are needed by clients are implemented at this time.
aoqi@0 42 * This is used during default method analysis to create overpass methods
aoqi@0 43 * and add them to a call during parsing. Other uses (such as creating
aoqi@0 44 * bridges) may come later. Any missing bytecodes can be implemented on an
aoqi@0 45 * as-need basis.
aoqi@0 46 */
aoqi@0 47
aoqi@0 48 class BytecodeBuffer : public GrowableArray<u1> {
aoqi@0 49 public:
aoqi@0 50 BytecodeBuffer() : GrowableArray<u1>(20) {}
aoqi@0 51 };
aoqi@0 52
aoqi@0 53 // Entries in a yet-to-be-created constant pool. Limited types for now.
aoqi@0 54 class BytecodeCPEntry VALUE_OBJ_CLASS_SPEC {
aoqi@0 55 public:
aoqi@0 56 enum tag {
aoqi@0 57 ERROR_TAG,
aoqi@0 58 UTF8,
aoqi@0 59 KLASS,
aoqi@0 60 STRING,
aoqi@0 61 NAME_AND_TYPE,
aoqi@0 62 METHODREF
aoqi@0 63 };
aoqi@0 64
aoqi@0 65 u1 _tag;
aoqi@0 66 union {
aoqi@0 67 Symbol* utf8;
aoqi@0 68 u2 klass;
aoqi@0 69 u2 string;
aoqi@0 70 struct {
aoqi@0 71 u2 name_index;
aoqi@0 72 u2 type_index;
aoqi@0 73 } name_and_type;
aoqi@0 74 struct {
aoqi@0 75 u2 class_index;
aoqi@0 76 u2 name_and_type_index;
aoqi@0 77 } methodref;
aoqi@0 78 uintptr_t hash;
aoqi@0 79 } _u;
aoqi@0 80
aoqi@0 81 BytecodeCPEntry() : _tag(ERROR_TAG) { _u.hash = 0; }
aoqi@0 82 BytecodeCPEntry(u1 tag) : _tag(tag) { _u.hash = 0; }
aoqi@0 83
aoqi@0 84 static BytecodeCPEntry utf8(Symbol* symbol) {
aoqi@0 85 BytecodeCPEntry bcpe(UTF8);
aoqi@0 86 bcpe._u.utf8 = symbol;
aoqi@0 87 return bcpe;
aoqi@0 88 }
aoqi@0 89
aoqi@0 90 static BytecodeCPEntry klass(u2 index) {
aoqi@0 91 BytecodeCPEntry bcpe(KLASS);
aoqi@0 92 bcpe._u.klass = index;
aoqi@0 93 return bcpe;
aoqi@0 94 }
aoqi@0 95
aoqi@0 96 static BytecodeCPEntry string(u2 index) {
aoqi@0 97 BytecodeCPEntry bcpe(STRING);
aoqi@0 98 bcpe._u.string = index;
aoqi@0 99 return bcpe;
aoqi@0 100 }
aoqi@0 101
aoqi@0 102 static BytecodeCPEntry name_and_type(u2 name, u2 type) {
aoqi@0 103 BytecodeCPEntry bcpe(NAME_AND_TYPE);
aoqi@0 104 bcpe._u.name_and_type.name_index = name;
aoqi@0 105 bcpe._u.name_and_type.type_index = type;
aoqi@0 106 return bcpe;
aoqi@0 107 }
aoqi@0 108
aoqi@0 109 static BytecodeCPEntry methodref(u2 class_index, u2 nat) {
aoqi@0 110 BytecodeCPEntry bcpe(METHODREF);
aoqi@0 111 bcpe._u.methodref.class_index = class_index;
aoqi@0 112 bcpe._u.methodref.name_and_type_index = nat;
aoqi@0 113 return bcpe;
aoqi@0 114 }
aoqi@0 115
aoqi@0 116 static bool equals(BytecodeCPEntry const& e0, BytecodeCPEntry const& e1) {
aoqi@0 117 return e0._tag == e1._tag && e0._u.hash == e1._u.hash;
aoqi@0 118 }
aoqi@0 119
aoqi@0 120 static unsigned hash(BytecodeCPEntry const& e0) {
aoqi@0 121 return (unsigned)(e0._tag ^ e0._u.hash);
aoqi@0 122 }
aoqi@0 123 };
aoqi@0 124
aoqi@0 125 class BytecodeConstantPool : ResourceObj {
aoqi@0 126 private:
aoqi@0 127 typedef ResourceHashtable<BytecodeCPEntry, u2,
aoqi@0 128 &BytecodeCPEntry::hash, &BytecodeCPEntry::equals> IndexHash;
aoqi@0 129
aoqi@0 130 ConstantPool* _orig;
aoqi@0 131 GrowableArray<BytecodeCPEntry> _entries;
aoqi@0 132 IndexHash _indices;
aoqi@0 133
aoqi@0 134 u2 find_or_add(BytecodeCPEntry const& bcpe);
aoqi@0 135
aoqi@0 136 public:
aoqi@0 137
aoqi@0 138 BytecodeConstantPool(ConstantPool* orig) : _orig(orig) {}
aoqi@0 139
aoqi@0 140 BytecodeCPEntry const& at(u2 index) const { return _entries.at(index); }
aoqi@0 141
aoqi@0 142 InstanceKlass* pool_holder() const {
aoqi@0 143 return InstanceKlass::cast(_orig->pool_holder());
aoqi@0 144 }
aoqi@0 145
aoqi@0 146 u2 utf8(Symbol* sym) {
aoqi@0 147 return find_or_add(BytecodeCPEntry::utf8(sym));
aoqi@0 148 }
aoqi@0 149
aoqi@0 150 u2 klass(Symbol* class_name) {
aoqi@0 151 return find_or_add(BytecodeCPEntry::klass(utf8(class_name)));
aoqi@0 152 }
aoqi@0 153
aoqi@0 154 u2 string(Symbol* str) {
aoqi@0 155 return find_or_add(BytecodeCPEntry::string(utf8(str)));
aoqi@0 156 }
aoqi@0 157
aoqi@0 158 u2 name_and_type(Symbol* name, Symbol* sig) {
aoqi@0 159 return find_or_add(BytecodeCPEntry::name_and_type(utf8(name), utf8(sig)));
aoqi@0 160 }
aoqi@0 161
aoqi@0 162 u2 methodref(Symbol* class_name, Symbol* name, Symbol* sig) {
aoqi@0 163 return find_or_add(BytecodeCPEntry::methodref(
aoqi@0 164 klass(class_name), name_and_type(name, sig)));
aoqi@0 165 }
aoqi@0 166
aoqi@0 167 ConstantPool* create_constant_pool(TRAPS) const;
aoqi@0 168 };
aoqi@0 169
aoqi@0 170 // Partial bytecode assembler - only what we need for creating
aoqi@0 171 // overpass methods for default methods is implemented
aoqi@0 172 class BytecodeAssembler : StackObj {
aoqi@0 173 private:
aoqi@0 174 BytecodeBuffer* _code;
aoqi@0 175 BytecodeConstantPool* _cp;
aoqi@0 176
aoqi@0 177 void append(u1 imm_u1);
aoqi@0 178 void append(u2 imm_u2);
aoqi@0 179 void append(u4 imm_u4);
aoqi@0 180
aoqi@0 181 void xload(u4 index, u1 quick, u1 twobyte);
aoqi@0 182
aoqi@0 183 public:
aoqi@0 184 BytecodeAssembler(BytecodeBuffer* buffer, BytecodeConstantPool* cp)
aoqi@0 185 : _code(buffer), _cp(cp) {}
aoqi@0 186
aoqi@0 187 void aload(u4 index);
aoqi@0 188 void areturn();
aoqi@0 189 void athrow();
aoqi@0 190 void checkcast(Symbol* sym);
aoqi@0 191 void dload(u4 index);
aoqi@0 192 void dreturn();
aoqi@0 193 void dup();
aoqi@0 194 void fload(u4 index);
aoqi@0 195 void freturn();
aoqi@0 196 void iload(u4 index);
aoqi@0 197 void invokespecial(Method* method);
aoqi@0 198 void invokespecial(Symbol* cls, Symbol* name, Symbol* sig);
aoqi@0 199 void invokevirtual(Method* method);
aoqi@0 200 void invokevirtual(Symbol* cls, Symbol* name, Symbol* sig);
aoqi@0 201 void ireturn();
aoqi@0 202 void ldc(u1 index);
aoqi@0 203 void ldc_w(u2 index);
aoqi@0 204 void lload(u4 index);
aoqi@0 205 void lreturn();
aoqi@0 206 void _new(Symbol* sym);
aoqi@0 207 void _return();
aoqi@0 208
aoqi@0 209 void load_string(Symbol* sym);
aoqi@0 210 void load(BasicType bt, u4 index);
aoqi@0 211 void _return(BasicType bt);
aoqi@0 212 };
aoqi@0 213
aoqi@0 214 #endif // SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP

mercurial