1 /*
2 * Copyright (c) 2003, 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 *
30 import sun.jvm.hotspot.debugger.*;
31 import sun.jvm.hotspot.interpreter.*;
32 import sun.jvm.hotspot.memory.*;
33 import sun.jvm.hotspot.runtime.*;
34 import sun.jvm.hotspot.types.*;
35 import sun.jvm.hotspot.utilities.*;
36
37 public class ConstMethod extends Oop {
38 static {
39 VM.registerVMInitializedObserver(new Observer() {
40 public void update(Observable o, Object data) {
41 initialize(VM.getVM().getTypeDataBase());
42 }
43 });
44 }
45
46 // anon-enum constants for _flags.
47 private static int HAS_LINENUMBER_TABLE;
48 private static int HAS_CHECKED_EXCEPTIONS;
49 private static int HAS_LOCALVARIABLE_TABLE;
50
51 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
52 Type type = db.lookupType("constMethodOopDesc");
53 // Backpointer to non-const methodOop
54 method = new OopField(type.getOopField("_method"), 0);
55 // The exception handler table. 4-tuples of ints [start_pc, end_pc,
56 // handler_pc, catch_type index] For methods with no exceptions the
57 // table is pointing to Universe::the_empty_int_array
58 exceptionTable = new OopField(type.getOopField("_exception_table"), 0);
59 constMethodSize = new CIntField(type.getCIntegerField("_constMethod_size"), 0);
60 flags = new ByteField(type.getJByteField("_flags"), 0);
61
62 // enum constants for flags
63 HAS_LINENUMBER_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_linenumber_table").intValue();
64 HAS_CHECKED_EXCEPTIONS = db.lookupIntConstant("constMethodOopDesc::_has_checked_exceptions").intValue();
65 HAS_LOCALVARIABLE_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_localvariable_table").intValue();
66
67 // Size of Java bytecodes allocated immediately after constMethodOop.
68 codeSize = new CIntField(type.getCIntegerField("_code_size"), 0);
69 nameIndex = new CIntField(type.getCIntegerField("_name_index"), 0);
70 signatureIndex = new CIntField(type.getCIntegerField("_signature_index"), 0);
71 genericSignatureIndex = new CIntField(type.getCIntegerField("_generic_signature_index"),0);
72
73 // start of byte code
74 bytecodeOffset = type.getSize();
75
76 type = db.lookupType("CheckedExceptionElement");
77 checkedExceptionElementSize = type.getSize();
78
79 type = db.lookupType("LocalVariableTableElement");
80 localVariableTableElementSize = type.getSize();
81 }
82
83 ConstMethod(OopHandle handle, ObjectHeap heap) {
84 super(handle, heap);
85 }
86
87 // Fields
88 private static OopField method;
89 private static OopField exceptionTable;
90 private static CIntField constMethodSize;
91 private static ByteField flags;
92 private static CIntField codeSize;
93 private static CIntField nameIndex;
94 private static CIntField signatureIndex;
95 private static CIntField genericSignatureIndex;
96
97 // start of bytecode
98 private static long bytecodeOffset;
99
100 private static long checkedExceptionElementSize;
101 private static long localVariableTableElementSize;
102
103 // Accessors for declared fields
104 public Method getMethod() {
105 return (Method) method.getValue(this);
106 }
107
108 public TypeArray getExceptionTable() {
109 return (TypeArray) exceptionTable.getValue(this);
110 }
111
112 public long getConstMethodSize() {
113 return constMethodSize.getValue(this);
114 }
115
116 public byte getFlags() {
117 return flags.getValue(this);
118 }
119
120 public long getCodeSize() {
121 return codeSize.getValue(this);
122 }
123
124 public long getNameIndex() {
125 return nameIndex.getValue(this);
126 }
127
128 public long getSignatureIndex() {
129 return signatureIndex.getValue(this);
130 }
131
207 for( int i=0; i < bc.length; i++ )
208 {
209 long offs = bytecodeOffset + i;
210 bc[i] = getHandle().getJByteAt( offs );
211 }
212 return bc;
213 }
214
215 public long getObjectSize() {
216 return getConstMethodSize() * getHeap().getOopSize();
217 }
218
219 public void printValueOn(PrintStream tty) {
220 tty.print("ConstMethod " + getName().asString() + getSignature().asString() + "@" + getHandle());
221 }
222
223 public void iterateFields(OopVisitor visitor, boolean doVMFields) {
224 super.iterateFields(visitor, doVMFields);
225 if (doVMFields) {
226 visitor.doOop(method, true);
227 visitor.doOop(exceptionTable, true);
228 visitor.doCInt(constMethodSize, true);
229 visitor.doByte(flags, true);
230 visitor.doCInt(codeSize, true);
231 visitor.doCInt(nameIndex, true);
232 visitor.doCInt(signatureIndex, true);
233 visitor.doCInt(genericSignatureIndex, true);
234 visitor.doCInt(codeSize, true);
235 }
236 }
237
238 // Accessors
239
240 public boolean hasLineNumberTable() {
241 return (getFlags() & HAS_LINENUMBER_TABLE) != 0;
242 }
243
244 public int getLineNumberFromBCI(int bci) {
245 if (!VM.getVM().isCore()) {
246 if (bci == DebugInformationRecorder.SYNCHRONIZATION_ENTRY_BCI) bci = 0;
247 }
298 }
299
300 public Symbol getLocalVariableName(int bci, int slot) {
301 return getMethod().getLocalVariableName(bci, slot);
302 }
303
304 /** Should only be called if table is present */
305 public LocalVariableTableElement[] getLocalVariableTable() {
306 if (Assert.ASSERTS_ENABLED) {
307 Assert.that(hasLocalVariableTable(), "should only be called if table is present");
308 }
309 LocalVariableTableElement[] ret = new LocalVariableTableElement[getLocalVariableTableLength()];
310 long offset = offsetOfLocalVariableTable();
311 for (int i = 0; i < ret.length; i++) {
312 ret[i] = new LocalVariableTableElement(getHandle(), offset);
313 offset += localVariableTableElementSize;
314 }
315 return ret;
316 }
317
318 public boolean hasCheckedExceptions() {
319 return (getFlags() & HAS_CHECKED_EXCEPTIONS) != 0;
320 }
321
322 public CheckedExceptionElement[] getCheckedExceptions() {
323 if (Assert.ASSERTS_ENABLED) {
324 Assert.that(hasCheckedExceptions(), "should only be called if table is present");
325 }
326 CheckedExceptionElement[] ret = new CheckedExceptionElement[getCheckedExceptionsLength()];
327 long offset = offsetOfCheckedExceptions();
328 for (int i = 0; i < ret.length; i++) {
329 ret[i] = new CheckedExceptionElement(getHandle(), offset);
330 offset += checkedExceptionElementSize;
331 }
332 return ret;
333 }
334
335
336 //---------------------------------------------------------------------------
337 // Internals only below this point
387 while (stream.readPair()) {
388 len += 1;
389 }
390 }
391 return len;
392 }
393
394 private int getLocalVariableTableLength() {
395 if (hasLocalVariableTable()) {
396 return (int) getHandle().getCIntegerAt(offsetOfLocalVariableTableLength(), 2, true);
397 } else {
398 return 0;
399 }
400 }
401
402 // Offset of local variable table length
403 private long offsetOfLocalVariableTableLength() {
404 if (Assert.ASSERTS_ENABLED) {
405 Assert.that(hasLocalVariableTable(), "should only be called if table is present");
406 }
407 if (hasCheckedExceptions()) {
408 return offsetOfCheckedExceptions() - 2;
409 } else {
410 return offsetOfLastU2Element();
411 }
412 }
413
414 private long offsetOfLocalVariableTable() {
415 long offset = offsetOfLocalVariableTableLength();
416 long length = getLocalVariableTableLength();
417 if (Assert.ASSERTS_ENABLED) {
418 Assert.that(length > 0, "should only be called if table is present");
419 }
420 offset -= length * localVariableTableElementSize;
421 return offset;
422 }
423
424 }
|
1 /*
2 * Copyright (c) 2003, 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 *
30 import sun.jvm.hotspot.debugger.*;
31 import sun.jvm.hotspot.interpreter.*;
32 import sun.jvm.hotspot.memory.*;
33 import sun.jvm.hotspot.runtime.*;
34 import sun.jvm.hotspot.types.*;
35 import sun.jvm.hotspot.utilities.*;
36
37 public class ConstMethod extends Oop {
38 static {
39 VM.registerVMInitializedObserver(new Observer() {
40 public void update(Observable o, Object data) {
41 initialize(VM.getVM().getTypeDataBase());
42 }
43 });
44 }
45
46 // anon-enum constants for _flags.
47 private static int HAS_LINENUMBER_TABLE;
48 private static int HAS_CHECKED_EXCEPTIONS;
49 private static int HAS_LOCALVARIABLE_TABLE;
50 private static int HAS_EXCEPTION_TABLE;
51
52 private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
53 Type type = db.lookupType("constMethodOopDesc");
54 // Backpointer to non-const methodOop
55 method = new OopField(type.getOopField("_method"), 0);
56 constMethodSize = new CIntField(type.getCIntegerField("_constMethod_size"), 0);
57 flags = new ByteField(type.getJByteField("_flags"), 0);
58
59 // enum constants for flags
60 HAS_LINENUMBER_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_linenumber_table").intValue();
61 HAS_CHECKED_EXCEPTIONS = db.lookupIntConstant("constMethodOopDesc::_has_checked_exceptions").intValue();
62 HAS_LOCALVARIABLE_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_localvariable_table").intValue();
63 HAS_EXCEPTION_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_exception_table").intValue();
64
65 // Size of Java bytecodes allocated immediately after constMethodOop.
66 codeSize = new CIntField(type.getCIntegerField("_code_size"), 0);
67 nameIndex = new CIntField(type.getCIntegerField("_name_index"), 0);
68 signatureIndex = new CIntField(type.getCIntegerField("_signature_index"), 0);
69 genericSignatureIndex = new CIntField(type.getCIntegerField("_generic_signature_index"),0);
70
71 // start of byte code
72 bytecodeOffset = type.getSize();
73
74 type = db.lookupType("CheckedExceptionElement");
75 checkedExceptionElementSize = type.getSize();
76
77 type = db.lookupType("LocalVariableTableElement");
78 localVariableTableElementSize = type.getSize();
79
80 type = db.lookupType("ExceptionTableElement");
81 exceptionTableElementSize = type.getSize();
82 }
83
84 ConstMethod(OopHandle handle, ObjectHeap heap) {
85 super(handle, heap);
86 }
87
88 // Fields
89 private static OopField method;
90 private static CIntField constMethodSize;
91 private static ByteField flags;
92 private static CIntField codeSize;
93 private static CIntField nameIndex;
94 private static CIntField signatureIndex;
95 private static CIntField genericSignatureIndex;
96
97 // start of bytecode
98 private static long bytecodeOffset;
99
100 private static long checkedExceptionElementSize;
101 private static long localVariableTableElementSize;
102 private static long exceptionTableElementSize;
103
104 // Accessors for declared fields
105 public Method getMethod() {
106 return (Method) method.getValue(this);
107 }
108
109 public long getConstMethodSize() {
110 return constMethodSize.getValue(this);
111 }
112
113 public byte getFlags() {
114 return flags.getValue(this);
115 }
116
117 public long getCodeSize() {
118 return codeSize.getValue(this);
119 }
120
121 public long getNameIndex() {
122 return nameIndex.getValue(this);
123 }
124
125 public long getSignatureIndex() {
126 return signatureIndex.getValue(this);
127 }
128
204 for( int i=0; i < bc.length; i++ )
205 {
206 long offs = bytecodeOffset + i;
207 bc[i] = getHandle().getJByteAt( offs );
208 }
209 return bc;
210 }
211
212 public long getObjectSize() {
213 return getConstMethodSize() * getHeap().getOopSize();
214 }
215
216 public void printValueOn(PrintStream tty) {
217 tty.print("ConstMethod " + getName().asString() + getSignature().asString() + "@" + getHandle());
218 }
219
220 public void iterateFields(OopVisitor visitor, boolean doVMFields) {
221 super.iterateFields(visitor, doVMFields);
222 if (doVMFields) {
223 visitor.doOop(method, true);
224 visitor.doCInt(constMethodSize, true);
225 visitor.doByte(flags, true);
226 visitor.doCInt(codeSize, true);
227 visitor.doCInt(nameIndex, true);
228 visitor.doCInt(signatureIndex, true);
229 visitor.doCInt(genericSignatureIndex, true);
230 visitor.doCInt(codeSize, true);
231 }
232 }
233
234 // Accessors
235
236 public boolean hasLineNumberTable() {
237 return (getFlags() & HAS_LINENUMBER_TABLE) != 0;
238 }
239
240 public int getLineNumberFromBCI(int bci) {
241 if (!VM.getVM().isCore()) {
242 if (bci == DebugInformationRecorder.SYNCHRONIZATION_ENTRY_BCI) bci = 0;
243 }
294 }
295
296 public Symbol getLocalVariableName(int bci, int slot) {
297 return getMethod().getLocalVariableName(bci, slot);
298 }
299
300 /** Should only be called if table is present */
301 public LocalVariableTableElement[] getLocalVariableTable() {
302 if (Assert.ASSERTS_ENABLED) {
303 Assert.that(hasLocalVariableTable(), "should only be called if table is present");
304 }
305 LocalVariableTableElement[] ret = new LocalVariableTableElement[getLocalVariableTableLength()];
306 long offset = offsetOfLocalVariableTable();
307 for (int i = 0; i < ret.length; i++) {
308 ret[i] = new LocalVariableTableElement(getHandle(), offset);
309 offset += localVariableTableElementSize;
310 }
311 return ret;
312 }
313
314 public boolean hasExceptionTable() {
315 return (getFlags() & HAS_EXCEPTION_TABLE) != 0;
316 }
317
318 public ExceptionTableElement[] getExceptionTable() {
319 if (Assert.ASSERTS_ENABLED) {
320 Assert.that(hasExceptionTable(), "should only be called if table is present");
321 }
322 ExceptionTableElement[] ret = new ExceptionTableElement[getExceptionTableLength()];
323 long offset = offsetOfExceptionTable();
324 for (int i = 0; i < ret.length; i++) {
325 ret[i] = new ExceptionTableElement(getHandle(), offset);
326 offset += exceptionTableElementSize;
327 }
328 return ret;
329 }
330
331 public boolean hasCheckedExceptions() {
332 return (getFlags() & HAS_CHECKED_EXCEPTIONS) != 0;
333 }
334
335 public CheckedExceptionElement[] getCheckedExceptions() {
336 if (Assert.ASSERTS_ENABLED) {
337 Assert.that(hasCheckedExceptions(), "should only be called if table is present");
338 }
339 CheckedExceptionElement[] ret = new CheckedExceptionElement[getCheckedExceptionsLength()];
340 long offset = offsetOfCheckedExceptions();
341 for (int i = 0; i < ret.length; i++) {
342 ret[i] = new CheckedExceptionElement(getHandle(), offset);
343 offset += checkedExceptionElementSize;
344 }
345 return ret;
346 }
347
348
349 //---------------------------------------------------------------------------
350 // Internals only below this point
400 while (stream.readPair()) {
401 len += 1;
402 }
403 }
404 return len;
405 }
406
407 private int getLocalVariableTableLength() {
408 if (hasLocalVariableTable()) {
409 return (int) getHandle().getCIntegerAt(offsetOfLocalVariableTableLength(), 2, true);
410 } else {
411 return 0;
412 }
413 }
414
415 // Offset of local variable table length
416 private long offsetOfLocalVariableTableLength() {
417 if (Assert.ASSERTS_ENABLED) {
418 Assert.that(hasLocalVariableTable(), "should only be called if table is present");
419 }
420
421 if (hasExceptionTable()) {
422 return offsetOfExceptionTable() - 2;
423 } else if (hasCheckedExceptions()) {
424 return offsetOfCheckedExceptions() - 2;
425 } else {
426 return offsetOfLastU2Element();
427 }
428 }
429
430 private long offsetOfLocalVariableTable() {
431 long offset = offsetOfLocalVariableTableLength();
432 long length = getLocalVariableTableLength();
433 if (Assert.ASSERTS_ENABLED) {
434 Assert.that(length > 0, "should only be called if table is present");
435 }
436 offset -= length * localVariableTableElementSize;
437 return offset;
438 }
439
440 private int getExceptionTableLength() {
441 if (hasExceptionTable()) {
442 return (int) getHandle().getCIntegerAt(offsetOfExceptionTableLength(), 2, true);
443 } else {
444 return 0;
445 }
446 }
447
448 private long offsetOfExceptionTableLength() {
449 if (Assert.ASSERTS_ENABLED) {
450 Assert.that(hasExceptionTable(), "should only be called if table is present");
451 }
452 if (hasCheckedExceptions()) {
453 return offsetOfCheckedExceptions() - 2;
454 } else {
455 return offsetOfLastU2Element();
456 }
457 }
458
459 private long offsetOfExceptionTable() {
460 long offset = offsetOfExceptionTableLength();
461 long length = getExceptionTableLength();
462 if (Assert.ASSERTS_ENABLED) {
463 Assert.that(length > 0, "should only be called if table is present");
464 }
465 offset -= length * exceptionTableElementSize;
466 return offset;
467 }
468
469 }
|