Mercurial > hg > truffle
comparison src/share/vm/classfile/bytecodeAssembler.hpp @ 6934:4735d2c84362
7200776: Implement default methods in interfaces
Summary: Add generic type analysis and default method selection algorithms
Reviewed-by: coleenp, acorn
author | kamg |
---|---|
date | Thu, 11 Oct 2012 12:25:42 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
6921:a1b8cf9cf970 | 6934:4735d2c84362 |
---|---|
1 /* | |
2 * Copyright (c) 2012, 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 #ifndef SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP | |
26 #define SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP | |
27 | |
28 #include "memory/allocation.hpp" | |
29 #include "oops/method.hpp" | |
30 #include "oops/symbol.hpp" | |
31 #include "utilities/globalDefinitions.hpp" | |
32 #include "utilities/growableArray.hpp" | |
33 #include "utilities/resourceHash.hpp" | |
34 | |
35 | |
36 /** | |
37 * Bytecode Assembler | |
38 * | |
39 * These classes are used to synthesize code for creating new methods from | |
40 * within the VM. This is only a partial implementation of an assembler; | |
41 * only the bytecodes that are needed by clients are implemented at this time. | |
42 * This is used during default method analysis to create overpass methods | |
43 * and add them to a call during parsing. Other uses (such as creating | |
44 * bridges) may come later. Any missing bytecodes can be implemented on an | |
45 * as-need basis. | |
46 */ | |
47 | |
48 class BytecodeBuffer : public GrowableArray<u1> { | |
49 public: | |
50 BytecodeBuffer() : GrowableArray<u1>(20) {} | |
51 }; | |
52 | |
53 // Entries in a yet-to-be-created constant pool. Limited types for now. | |
54 class BytecodeCPEntry VALUE_OBJ_CLASS_SPEC { | |
55 public: | |
56 enum tag { | |
57 ERROR_TAG, | |
58 UTF8, | |
59 KLASS, | |
60 STRING, | |
61 NAME_AND_TYPE, | |
62 METHODREF | |
63 }; | |
64 | |
65 u1 _tag; | |
66 union { | |
67 Symbol* utf8; | |
68 u2 klass; | |
69 u2 string; | |
70 struct { | |
71 u2 name_index; | |
72 u2 type_index; | |
73 } name_and_type; | |
74 struct { | |
75 u2 class_index; | |
76 u2 name_and_type_index; | |
77 } methodref; | |
78 uintptr_t hash; | |
79 } _u; | |
80 | |
81 BytecodeCPEntry() : _tag(ERROR_TAG) { _u.hash = 0; } | |
82 BytecodeCPEntry(u1 tag) : _tag(tag) { _u.hash = 0; } | |
83 | |
84 static BytecodeCPEntry utf8(Symbol* symbol) { | |
85 BytecodeCPEntry bcpe(UTF8); | |
86 bcpe._u.utf8 = symbol; | |
87 return bcpe; | |
88 } | |
89 | |
90 static BytecodeCPEntry klass(u2 index) { | |
91 BytecodeCPEntry bcpe(KLASS); | |
92 bcpe._u.klass = index; | |
93 return bcpe; | |
94 } | |
95 | |
96 static BytecodeCPEntry string(u2 index) { | |
97 BytecodeCPEntry bcpe(STRING); | |
98 bcpe._u.string = index; | |
99 return bcpe; | |
100 } | |
101 | |
102 static BytecodeCPEntry name_and_type(u2 name, u2 type) { | |
103 BytecodeCPEntry bcpe(NAME_AND_TYPE); | |
104 bcpe._u.name_and_type.name_index = name; | |
105 bcpe._u.name_and_type.type_index = type; | |
106 return bcpe; | |
107 } | |
108 | |
109 static BytecodeCPEntry methodref(u2 class_index, u2 nat) { | |
110 BytecodeCPEntry bcpe(METHODREF); | |
111 bcpe._u.methodref.class_index = class_index; | |
112 bcpe._u.methodref.name_and_type_index = nat; | |
113 return bcpe; | |
114 } | |
115 | |
116 static bool equals(BytecodeCPEntry const& e0, BytecodeCPEntry const& e1) { | |
117 return e0._tag == e1._tag && e0._u.hash == e1._u.hash; | |
118 } | |
119 | |
120 static unsigned hash(BytecodeCPEntry const& e0) { | |
121 return (unsigned)(e0._tag ^ e0._u.hash); | |
122 } | |
123 }; | |
124 | |
125 class BytecodeConstantPool : ResourceObj { | |
126 private: | |
127 typedef ResourceHashtable<BytecodeCPEntry, u2, | |
128 &BytecodeCPEntry::hash, &BytecodeCPEntry::equals> IndexHash; | |
129 | |
130 ConstantPool* _orig; | |
131 GrowableArray<BytecodeCPEntry> _entries; | |
132 IndexHash _indices; | |
133 | |
134 u2 find_or_add(BytecodeCPEntry const& bcpe); | |
135 | |
136 public: | |
137 | |
138 BytecodeConstantPool(ConstantPool* orig) : _orig(orig) {} | |
139 | |
140 BytecodeCPEntry const& at(u2 index) const { return _entries.at(index); } | |
141 | |
142 InstanceKlass* pool_holder() const { | |
143 return InstanceKlass::cast(_orig->pool_holder()); | |
144 } | |
145 | |
146 u2 utf8(Symbol* sym) { | |
147 return find_or_add(BytecodeCPEntry::utf8(sym)); | |
148 } | |
149 | |
150 u2 klass(Symbol* class_name) { | |
151 return find_or_add(BytecodeCPEntry::klass(utf8(class_name))); | |
152 } | |
153 | |
154 u2 string(Symbol* str) { | |
155 return find_or_add(BytecodeCPEntry::string(utf8(str))); | |
156 } | |
157 | |
158 u2 name_and_type(Symbol* name, Symbol* sig) { | |
159 return find_or_add(BytecodeCPEntry::name_and_type(utf8(name), utf8(sig))); | |
160 } | |
161 | |
162 u2 methodref(Symbol* class_name, Symbol* name, Symbol* sig) { | |
163 return find_or_add(BytecodeCPEntry::methodref( | |
164 klass(class_name), name_and_type(name, sig))); | |
165 } | |
166 | |
167 ConstantPool* create_constant_pool(TRAPS) const; | |
168 }; | |
169 | |
170 // Partial bytecode assembler - only what we need for creating | |
171 // overpass methods for default methods is implemented | |
172 class BytecodeAssembler : StackObj { | |
173 private: | |
174 BytecodeBuffer* _code; | |
175 BytecodeConstantPool* _cp; | |
176 | |
177 void append(u1 imm_u1); | |
178 void append(u2 imm_u2); | |
179 void append(u4 imm_u4); | |
180 | |
181 void xload(u4 index, u1 quick, u1 twobyte); | |
182 | |
183 public: | |
184 BytecodeAssembler(BytecodeBuffer* buffer, BytecodeConstantPool* cp) | |
185 : _code(buffer), _cp(cp) {} | |
186 | |
187 void aload(u4 index); | |
188 void areturn(); | |
189 void athrow(); | |
190 void checkcast(Symbol* sym); | |
191 void dload(u4 index); | |
192 void dreturn(); | |
193 void dup(); | |
194 void fload(u4 index); | |
195 void freturn(); | |
196 void iload(u4 index); | |
197 void invokespecial(Method* method); | |
198 void invokespecial(Symbol* cls, Symbol* name, Symbol* sig); | |
199 void invokevirtual(Method* method); | |
200 void invokevirtual(Symbol* cls, Symbol* name, Symbol* sig); | |
201 void ireturn(); | |
202 void ldc(u1 index); | |
203 void ldc_w(u2 index); | |
204 void lload(u4 index); | |
205 void lreturn(); | |
206 void _new(Symbol* sym); | |
207 void _return(); | |
208 | |
209 void load_string(Symbol* sym); | |
210 void load(BasicType bt, u4 index); | |
211 void _return(BasicType bt); | |
212 }; | |
213 | |
214 #endif // SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP |