--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java Tue Jul 17 11:16:13 2012 -0700
@@ -47,14 +47,11 @@
private static int HAS_LINENUMBER_TABLE;
private static int HAS_CHECKED_EXCEPTIONS;
private static int HAS_LOCALVARIABLE_TABLE;
+ private static int HAS_EXCEPTION_TABLE;
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("constMethodOopDesc");
constants = new OopField(type.getOopField("_constants"), 0);
- // The exception handler table. 4-tuples of ints [start_pc, end_pc,
- // handler_pc, catch_type index] For methods with no exceptions the
- // table is pointing to Universe::the_empty_int_array
- exceptionTable = new OopField(type.getOopField("_exception_table"), 0);
constMethodSize = new CIntField(type.getCIntegerField("_constMethod_size"), 0);
flags = new ByteField(type.getJByteField("_flags"), 0);
@@ -62,6 +59,7 @@
HAS_LINENUMBER_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_linenumber_table").intValue();
HAS_CHECKED_EXCEPTIONS = db.lookupIntConstant("constMethodOopDesc::_has_checked_exceptions").intValue();
HAS_LOCALVARIABLE_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_localvariable_table").intValue();
+ HAS_EXCEPTION_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_exception_table").intValue();
// Size of Java bytecodes allocated immediately after constMethodOop.
codeSize = new CIntField(type.getCIntegerField("_code_size"), 0);
@@ -78,6 +76,9 @@
type = db.lookupType("LocalVariableTableElement");
localVariableTableElementSize = type.getSize();
+
+ type = db.lookupType("ExceptionTableElement");
+ exceptionTableElementSize = type.getSize();
}
ConstMethod(OopHandle handle, ObjectHeap heap) {
@@ -86,7 +87,6 @@
// Fields
private static OopField constants;
- private static OopField exceptionTable;
private static CIntField constMethodSize;
private static ByteField flags;
private static CIntField codeSize;
@@ -100,6 +100,7 @@
private static long checkedExceptionElementSize;
private static long localVariableTableElementSize;
+ private static long exceptionTableElementSize;
public Method getMethod() {
InstanceKlass ik = (InstanceKlass)getConstants().getPoolHolder();
@@ -112,10 +113,6 @@
return (ConstantPool) constants.getValue(this);
}
- public TypeArray getExceptionTable() {
- return (TypeArray) exceptionTable.getValue(this);
- }
-
public long getConstMethodSize() {
return constMethodSize.getValue(this);
}
@@ -235,7 +232,6 @@
super.iterateFields(visitor, doVMFields);
if (doVMFields) {
visitor.doOop(constants, true);
- visitor.doOop(exceptionTable, true);
visitor.doCInt(constMethodSize, true);
visitor.doByte(flags, true);
visitor.doCInt(codeSize, true);
@@ -326,6 +322,23 @@
return ret;
}
+ public boolean hasExceptionTable() {
+ return (getFlags() & HAS_EXCEPTION_TABLE) != 0;
+ }
+
+ public ExceptionTableElement[] getExceptionTable() {
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(hasExceptionTable(), "should only be called if table is present");
+ }
+ ExceptionTableElement[] ret = new ExceptionTableElement[getExceptionTableLength()];
+ long offset = offsetOfExceptionTable();
+ for (int i = 0; i < ret.length; i++) {
+ ret[i] = new ExceptionTableElement(getHandle(), offset);
+ offset += exceptionTableElementSize;
+ }
+ return ret;
+ }
+
public boolean hasCheckedExceptions() {
return (getFlags() & HAS_CHECKED_EXCEPTIONS) != 0;
}
@@ -415,7 +428,10 @@
if (Assert.ASSERTS_ENABLED) {
Assert.that(hasLocalVariableTable(), "should only be called if table is present");
}
- if (hasCheckedExceptions()) {
+
+ if (hasExceptionTable()) {
+ return offsetOfExceptionTable() - 2;
+ } else if (hasCheckedExceptions()) {
return offsetOfCheckedExceptions() - 2;
} else {
return offsetOfLastU2Element();
@@ -432,4 +448,33 @@
return offset;
}
+ private int getExceptionTableLength() {
+ if (hasExceptionTable()) {
+ return (int) getHandle().getCIntegerAt(offsetOfExceptionTableLength(), 2, true);
+ } else {
+ return 0;
+ }
+ }
+
+ private long offsetOfExceptionTableLength() {
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(hasExceptionTable(), "should only be called if table is present");
+ }
+ if (hasCheckedExceptions()) {
+ return offsetOfCheckedExceptions() - 2;
+ } else {
+ return offsetOfLastU2Element();
+ }
+ }
+
+ private long offsetOfExceptionTable() {
+ long offset = offsetOfExceptionTableLength();
+ long length = getExceptionTableLength();
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(length > 0, "should only be called if table is present");
+ }
+ offset -= length * exceptionTableElementSize;
+ return offset;
+ }
+
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ExceptionTableElement.java Tue Jul 17 11:16:13 2012 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.interpreter.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+public class ExceptionTableElement {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ExceptionTableElement");
+ offsetOfStartPC = type.getCIntegerField("start_pc").getOffset();
+ offsetOfEndPC = type.getCIntegerField("end_pc").getOffset();
+ offsetOfHandlerPC = type.getCIntegerField("handler_pc").getOffset();
+ offsetOfCatchTypeIndex = type.getCIntegerField("catch_type_index").getOffset();
+ }
+
+ private static long offsetOfStartPC;
+ private static long offsetOfEndPC;
+ private static long offsetOfHandlerPC;
+ private static long offsetOfCatchTypeIndex;
+
+ private OopHandle handle;
+ private long offset;
+
+ public ExceptionTableElement(OopHandle handle, long offset) {
+ this.handle = handle;
+ this.offset = offset;
+ }
+
+ public int getStartPC() {
+ return (int) handle.getCIntegerAt(offset + offsetOfStartPC, 2, true);
+ }
+
+ public int getEndPC() {
+ return (int) handle.getCIntegerAt(offset + offsetOfEndPC, 2, true);
+ }
+
+ public int getHandlerPC() {
+ return (int) handle.getCIntegerAt(offset + offsetOfHandlerPC, 2, true);
+ }
+
+ public int getCatchTypeIndex() {
+ return (int) handle.getCIntegerAt(offset + offsetOfCatchTypeIndex, 2, true);
+ }
+}
+
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java Tue Jul 17 11:16:13 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -651,10 +651,11 @@
boolean fellThrough = false; // False to get first BB marked.
// First mark all exception handlers as start of a basic-block
- TypeArray excps = method().getExceptionTable();
- for(int i = 0; i < excps.getLength(); i += 4) {
- int handler_pc_idx = i+2;
- markBB(excps.getIntAt(handler_pc_idx), null);
+ if (method().hasExceptionTable()) {
+ ExceptionTableElement[] excps = method().getExceptionTable();
+ for(int i = 0; i < excps.length; i++) {
+ markBB(excps[i].getHandlerPC(), null);
+ }
}
// Then iterate through the code
@@ -891,14 +892,15 @@
// Mark entry basic block as alive and all exception handlers
_basic_blocks[0].markAsAlive();
- TypeArray excps = method().getExceptionTable();
- for(int i = 0; i < excps.getLength(); i += 4) {
- int handler_pc_idx = i+2;
- BasicBlock bb = getBasicBlockAt(excps.getIntAt(handler_pc_idx));
- // If block is not already alive (due to multiple exception handlers to same bb), then
- // make it alive
- if (bb.isDead())
- bb.markAsAlive();
+ if (method().hasExceptionTable()) {
+ ExceptionTableElement[] excps = method().getExceptionTable();
+ for(int i = 0; i < excps.length; i ++) {
+ BasicBlock bb = getBasicBlockAt(excps[i].getHandlerPC());
+ // If block is not already alive (due to multiple exception handlers to same bb), then
+ // make it alive
+ if (bb.isDead())
+ bb.markAsAlive();
+ }
}
BytecodeStream bcs = new BytecodeStream(_method);
@@ -1468,12 +1470,12 @@
if (_has_exceptions) {
int bci = itr.bci();
- TypeArray exct = method().getExceptionTable();
- for(int i = 0; i< exct.getLength(); i+=4) {
- int start_pc = exct.getIntAt(i);
- int end_pc = exct.getIntAt(i+1);
- int handler_pc = exct.getIntAt(i+2);
- int catch_type = exct.getIntAt(i+3);
+ ExceptionTableElement[] exct = method().getExceptionTable();
+ for(int i = 0; i< exct.length; i++) {
+ int start_pc = exct[i].getStartPC();
+ int end_pc = exct[i].getEndPC();
+ int handler_pc = exct[i].getHandlerPC();
+ int catch_type = exct[i].getCatchTypeIndex();
if (start_pc <= bci && bci < end_pc) {
BasicBlock excBB = getBasicBlockAt(handler_pc);
@@ -2151,7 +2153,7 @@
_conflict = false;
_max_locals = (int) method().getMaxLocals();
_max_stack = (int) method().getMaxStack();
- _has_exceptions = (method().getExceptionTable().getLength() > 0);
+ _has_exceptions = (method().hasExceptionTable());
_nof_refval_conflicts = 0;
_init_vars = new ArrayList(5); // There are seldom more than 5 init_vars
_report_result = false;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Tue Jul 17 11:16:13 2012 -0700
@@ -127,7 +127,6 @@
return getConstMethod().getConstants();
}
public MethodData getMethodData() { return (MethodData) methodData.getValue(this); }
- public TypeArray getExceptionTable() { return getConstMethod().getExceptionTable(); }
/** WARNING: this is in words, not useful in this system; use getObjectSize() instead */
public long getMethodSize() { return methodSize.getValue(this); }
public long getMaxStack() { return maxStack.getValue(this); }
@@ -328,6 +327,14 @@
return null;
}
+ public boolean hasExceptionTable() {
+ return getConstMethod().hasExceptionTable();
+ }
+
+ public ExceptionTableElement[] getExceptionTable() {
+ return getConstMethod().getExceptionTable();
+ }
+
public boolean hasCheckedExceptions() {
return getConstMethod().hasCheckedExceptions();
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Tue Jul 17 11:16:13 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -504,11 +504,14 @@
2 /* exp. table len. */ +
2 /* code attr. count */;
- TypeArray exceptionTable = m.getExceptionTable();
- final int exceptionTableLen = (int) exceptionTable.getLength();
- if (exceptionTableLen != 0) {
+ boolean hasExceptionTable = m.hasExceptionTable();
+ ExceptionTableElement[] exceptionTable = null;
+ int exceptionTableLen = 0;
+ if (hasExceptionTable) {
+ exceptionTable = m.getExceptionTable();
+ exceptionTableLen = exceptionTable.length;
if (DEBUG) debugMessage("\tmethod has exception table");
- codeSize += (exceptionTableLen / 4) /* exception table is 4-tuple array */
+ codeSize += exceptionTableLen /* exception table is 4-tuple array */
* (2 /* start_pc */ +
2 /* end_pc */ +
2 /* handler_pc */ +
@@ -586,15 +589,15 @@
dos.write(code);
// write exception table size
- dos.writeShort((short) (exceptionTableLen / 4));
- if (DEBUG) debugMessage("\texception table length = " + (exceptionTableLen / 4));
+ dos.writeShort((short) exceptionTableLen);
+ if (DEBUG) debugMessage("\texception table length = " + exceptionTableLen);
if (exceptionTableLen != 0) {
- for (int e = 0; e < exceptionTableLen; e += 4) {
- dos.writeShort((short) exceptionTable.getIntAt(e));
- dos.writeShort((short) exceptionTable.getIntAt(e + 1));
- dos.writeShort((short) exceptionTable.getIntAt(e + 2));
- dos.writeShort((short) exceptionTable.getIntAt(e + 3));
+ for (int e = 0; e < exceptionTableLen; e++) {
+ dos.writeShort((short) exceptionTable[e].getStartPC());
+ dos.writeShort((short) exceptionTable[e].getEndPC());
+ dos.writeShort((short) exceptionTable[e].getHandlerPC());
+ dos.writeShort((short) exceptionTable[e].getCatchTypeIndex());
}
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Tue Jul 17 11:16:13 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -783,37 +783,39 @@
});
// display exception table for this method
- TypeArray exceptionTable = method.getExceptionTable();
- // exception table is 4 tuple array of shorts
- int numEntries = (int)exceptionTable.getLength() / 4;
- if (numEntries != 0) {
- buf.h4("Exception Table");
- buf.beginTable(1);
- buf.beginTag("tr");
- buf.headerCell("start bci");
- buf.headerCell("end bci");
- buf.headerCell("handler bci");
- buf.headerCell("catch type");
- buf.endTag("tr");
-
- for (int e = 0; e < numEntries; e += 4) {
+ boolean hasException = method.hasExceptionTable();
+ if (hasException) {
+ ExceptionTableElement[] exceptionTable = method.getExceptionTable();
+ int numEntries = exceptionTable.length;
+ if (numEntries != 0) {
+ buf.h4("Exception Table");
+ buf.beginTable(1);
buf.beginTag("tr");
- buf.cell(Integer.toString(exceptionTable.getIntAt(e)));
- buf.cell(Integer.toString(exceptionTable.getIntAt(e + 1)));
- buf.cell(Integer.toString(exceptionTable.getIntAt(e + 2)));
- short cpIndex = (short) exceptionTable.getIntAt(e + 3);
- ConstantPool.CPSlot obj = cpIndex == 0? null : cpool.getSlotAt(cpIndex);
- if (obj == null) {
- buf.cell("Any");
- } else if (obj.isMetaData()) {
- buf.cell(obj.getSymbol().asString().replace('/', '.'));
- } else {
- buf.cell(genKlassLink((InstanceKlass)obj.getOop()));
+ buf.headerCell("start bci");
+ buf.headerCell("end bci");
+ buf.headerCell("handler bci");
+ buf.headerCell("catch type");
+ buf.endTag("tr");
+
+ for (int e = 0; e < numEntries; e ++) {
+ buf.beginTag("tr");
+ buf.cell(Integer.toString(exceptionTable[e].getStartPC()));
+ buf.cell(Integer.toString(exceptionTable[e].getEndPC()));
+ buf.cell(Integer.toString(exceptionTable[e].getHandlerPC()));
+ short cpIndex = (short) exceptionTable[e].getCatchTypeIndex();
+ ConstantPool.CPSlot obj = cpIndex == 0? null : cpool.getSlotAt(cpIndex);
+ if (obj == null) {
+ buf.cell("Any");
+ } else if (obj.isMetaData()) {
+ buf.cell(obj.getSymbol().asString().replace('/', '.'));
+ } else {
+ buf.cell(genKlassLink((InstanceKlass)obj.getOop()));
+ }
+ buf.endTag("tr");
}
- buf.endTag("tr");
+
+ buf.endTable();
}
-
- buf.endTable();
}
// display constant pool hyperlink
--- a/hotspot/src/os/solaris/dtrace/libjvm_db.c Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/os/solaris/dtrace/libjvm_db.c Tue Jul 17 11:16:13 2012 -0700
@@ -516,7 +516,7 @@
err = read_pointer(J, methodOopPtr + OFFSET_methodOopDesc_constMethod, &constMethod);
CHECK_FAIL(err);
- err = read_pointer(J->P, constMethod + OFFSET_constMethodOopDesc_constants, &constantPool);
+ err = read_pointer(J, constMethod + OFFSET_constMethodOopDesc_constants, &constantPool);
CHECK_FAIL(err);
/* To get name string */
--- a/hotspot/src/share/vm/ci/ciMethod.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -79,7 +79,7 @@
_max_locals = h_m()->max_locals();
_code_size = h_m()->code_size();
_intrinsic_id = h_m()->intrinsic_id();
- _handler_count = h_m()->exception_table()->length() / 4;
+ _handler_count = h_m()->exception_table_length();
_uses_monitors = h_m()->access_flags().has_monitor_bytecodes();
_balanced_monitors = !_uses_monitors || h_m()->access_flags().is_monitor_matching();
_is_c1_compilable = !h_m()->is_not_c1_compilable();
@@ -198,7 +198,7 @@
}
// And load the exception table.
- typeArrayOop exc_table = me->exception_table();
+ ExceptionTable exc_table(me);
// Allocate one extra spot in our list of exceptions. This
// last entry will be used to represent the possibility that
@@ -209,13 +209,12 @@
* (_handler_count + 1));
if (_handler_count > 0) {
for (int i=0; i<_handler_count; i++) {
- int base = i*4;
_exception_handlers[i] = new (arena) ciExceptionHandler(
holder(),
- /* start */ exc_table->int_at(base),
- /* limit */ exc_table->int_at(base+1),
- /* goto pc */ exc_table->int_at(base+2),
- /* cp index */ exc_table->int_at(base+3));
+ /* start */ exc_table.start_pc(i),
+ /* limit */ exc_table.end_pc(i),
+ /* goto pc */ exc_table.handler_pc(i),
+ /* cp index */ exc_table.catch_type_index(i));
}
}
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -1296,42 +1296,38 @@
}
-typeArrayHandle ClassFileParser::parse_exception_table(u4 code_length,
- u4 exception_table_length,
- constantPoolHandle cp,
- TRAPS) {
+u2* ClassFileParser::parse_exception_table(u4 code_length,
+ u4 exception_table_length,
+ constantPoolHandle cp,
+ TRAPS) {
ClassFileStream* cfs = stream();
- typeArrayHandle nullHandle;
-
- // 4-tuples of ints [start_pc, end_pc, handler_pc, catch_type index]
- typeArrayOop eh = oopFactory::new_permanent_intArray(exception_table_length*4, CHECK_(nullHandle));
- typeArrayHandle exception_handlers = typeArrayHandle(THREAD, eh);
-
- int index = 0;
- cfs->guarantee_more(8 * exception_table_length, CHECK_(nullHandle)); // start_pc, end_pc, handler_pc, catch_type_index
- for (unsigned int i = 0; i < exception_table_length; i++) {
- u2 start_pc = cfs->get_u2_fast();
- u2 end_pc = cfs->get_u2_fast();
- u2 handler_pc = cfs->get_u2_fast();
- u2 catch_type_index = cfs->get_u2_fast();
- // Will check legal target after parsing code array in verifier.
- if (_need_verify) {
+
+ u2* exception_table_start = cfs->get_u2_buffer();
+ assert(exception_table_start != NULL, "null exception table");
+ cfs->guarantee_more(8 * exception_table_length, CHECK_NULL); // start_pc, end_pc, handler_pc, catch_type_index
+ // Will check legal target after parsing code array in verifier.
+ if (_need_verify) {
+ for (unsigned int i = 0; i < exception_table_length; i++) {
+ u2 start_pc = cfs->get_u2_fast();
+ u2 end_pc = cfs->get_u2_fast();
+ u2 handler_pc = cfs->get_u2_fast();
+ u2 catch_type_index = cfs->get_u2_fast();
guarantee_property((start_pc < end_pc) && (end_pc <= code_length),
- "Illegal exception table range in class file %s", CHECK_(nullHandle));
+ "Illegal exception table range in class file %s",
+ CHECK_NULL);
guarantee_property(handler_pc < code_length,
- "Illegal exception table handler in class file %s", CHECK_(nullHandle));
+ "Illegal exception table handler in class file %s",
+ CHECK_NULL);
if (catch_type_index != 0) {
guarantee_property(valid_cp_range(catch_type_index, cp->length()) &&
is_klass_reference(cp, catch_type_index),
- "Catch type in exception table has bad constant type in class file %s", CHECK_(nullHandle));
+ "Catch type in exception table has bad constant type in class file %s", CHECK_NULL);
}
}
- exception_handlers->int_at_put(index++, start_pc);
- exception_handlers->int_at_put(index++, end_pc);
- exception_handlers->int_at_put(index++, handler_pc);
- exception_handlers->int_at_put(index++, catch_type_index);
+ } else {
+ cfs->skip_u2_fast(exception_table_length * 4);
}
- return exception_handlers;
+ return exception_table_start;
}
void ClassFileParser::parse_linenumber_table(
@@ -1870,6 +1866,7 @@
u4 code_length = 0;
u1* code_start = 0;
u2 exception_table_length = 0;
+ u2* exception_table_start = NULL;
typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array());
u2 checked_exceptions_length = 0;
u2* checked_exceptions_start = NULL;
@@ -1957,7 +1954,7 @@
cfs->guarantee_more(2, CHECK_(nullHandle)); // exception_table_length
exception_table_length = cfs->get_u2_fast();
if (exception_table_length > 0) {
- exception_handlers =
+ exception_table_start =
parse_exception_table(code_length, exception_table_length, cp, CHECK_(nullHandle));
}
@@ -2162,9 +2159,13 @@
}
// All sizing information for a methodOop is finally available, now create it
- methodOop m_oop = oopFactory::new_method(code_length, access_flags, linenumber_table_length,
- total_lvt_length, checked_exceptions_length,
- oopDesc::IsSafeConc, CHECK_(nullHandle));
+ methodOop m_oop = oopFactory::new_method(code_length, access_flags,
+ linenumber_table_length,
+ total_lvt_length,
+ exception_table_length,
+ checked_exceptions_length,
+ oopDesc::IsSafeConc,
+ CHECK_(nullHandle));
methodHandle m (THREAD, m_oop);
ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize);
@@ -2195,16 +2196,15 @@
// Fill in code attribute information
m->set_max_stack(max_stack);
m->set_max_locals(max_locals);
- m->constMethod()->set_stackmap_data(stackmap_data());
/**
- * The exception_table field is the flag used to indicate
+ * The stackmap_data field is the flag used to indicate
* that the methodOop and it's associated constMethodOop are partially
* initialized and thus are exempt from pre/post GC verification. Once
* the field is set, the oops are considered fully initialized so make
* sure that the oops can pass verification when this field is set.
*/
- m->set_exception_table(exception_handlers());
+ m->constMethod()->set_stackmap_data(stackmap_data());
// Copy byte codes
m->set_code(code_start);
@@ -2215,6 +2215,14 @@
linenumber_table->buffer(), linenumber_table_length);
}
+ // Copy exception table
+ if (exception_table_length > 0) {
+ int size =
+ exception_table_length * sizeof(ExceptionTableElement) / sizeof(u2);
+ copy_u2_with_conversion((u2*) m->exception_table_start(),
+ exception_table_start, size);
+ }
+
// Copy checked exceptions
if (checked_exceptions_length > 0) {
int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2);
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Tue Jul 17 11:16:13 2012 -0700
@@ -184,8 +184,8 @@
objArrayHandle methods_parameter_annotations,
objArrayHandle methods_default_annotations,
TRAPS);
- typeArrayHandle parse_exception_table(u4 code_length, u4 exception_table_length,
- constantPoolHandle cp, TRAPS);
+ u2* parse_exception_table(u4 code_length, u4 exception_table_length,
+ constantPoolHandle cp, TRAPS);
void parse_linenumber_table(
u4 code_attribute_length, u4 code_length,
CompressedLineNumberWriteStream** write_stream, TRAPS);
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -2771,7 +2771,6 @@
nmethods++;
method_size += m->size();
// class loader uses same objArray for empty vectors, so don't count these
- if (m->exception_table()->length() != 0) method_size += m->exception_table()->size();
if (m->has_stackmap_table()) {
method_size += m->stackmap_data()->size();
}
--- a/hotspot/src/share/vm/classfile/verifier.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1368,47 +1368,48 @@
}
void ClassVerifier::verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS) {
- typeArrayHandle exhandlers (THREAD, _method->exception_table());
+ ExceptionTable exhandlers(_method());
+ int exlength = exhandlers.length();
constantPoolHandle cp (THREAD, _method->constants());
- if (exhandlers() != NULL) {
- for(int i = 0; i < exhandlers->length();) {
- u2 start_pc = exhandlers->int_at(i++);
- u2 end_pc = exhandlers->int_at(i++);
- u2 handler_pc = exhandlers->int_at(i++);
- if (start_pc >= code_length || code_data[start_pc] == 0) {
- class_format_error("Illegal exception table start_pc %d", start_pc);
+ for(int i = 0; i < exlength; i++) {
+ //reacquire the table in case a GC happened
+ ExceptionTable exhandlers(_method());
+ u2 start_pc = exhandlers.start_pc(i);
+ u2 end_pc = exhandlers.end_pc(i);
+ u2 handler_pc = exhandlers.handler_pc(i);
+ if (start_pc >= code_length || code_data[start_pc] == 0) {
+ class_format_error("Illegal exception table start_pc %d", start_pc);
+ return;
+ }
+ if (end_pc != code_length) { // special case: end_pc == code_length
+ if (end_pc > code_length || code_data[end_pc] == 0) {
+ class_format_error("Illegal exception table end_pc %d", end_pc);
return;
}
- if (end_pc != code_length) { // special case: end_pc == code_length
- if (end_pc > code_length || code_data[end_pc] == 0) {
- class_format_error("Illegal exception table end_pc %d", end_pc);
- return;
- }
- }
- if (handler_pc >= code_length || code_data[handler_pc] == 0) {
- class_format_error("Illegal exception table handler_pc %d", handler_pc);
+ }
+ if (handler_pc >= code_length || code_data[handler_pc] == 0) {
+ class_format_error("Illegal exception table handler_pc %d", handler_pc);
+ return;
+ }
+ int catch_type_index = exhandlers.catch_type_index(i);
+ if (catch_type_index != 0) {
+ VerificationType catch_type = cp_index_to_type(
+ catch_type_index, cp, CHECK_VERIFY(this));
+ VerificationType throwable =
+ VerificationType::reference_type(vmSymbols::java_lang_Throwable());
+ bool is_subclass = throwable.is_assignable_from(
+ catch_type, this, CHECK_VERIFY(this));
+ if (!is_subclass) {
+ // 4286534: should throw VerifyError according to recent spec change
+ verify_error(
+ "Catch type is not a subclass of Throwable in handler %d",
+ handler_pc);
return;
}
- int catch_type_index = exhandlers->int_at(i++);
- if (catch_type_index != 0) {
- VerificationType catch_type = cp_index_to_type(
- catch_type_index, cp, CHECK_VERIFY(this));
- VerificationType throwable =
- VerificationType::reference_type(vmSymbols::java_lang_Throwable());
- bool is_subclass = throwable.is_assignable_from(
- catch_type, this, CHECK_VERIFY(this));
- if (!is_subclass) {
- // 4286534: should throw VerifyError according to recent spec change
- verify_error(
- "Catch type is not a subclass of Throwable in handler %d",
- handler_pc);
- return;
- }
- }
- if (start_pc < min) min = start_pc;
- if (end_pc > max) max = end_pc;
}
+ if (start_pc < min) min = start_pc;
+ if (end_pc > max) max = end_pc;
}
}
@@ -1474,35 +1475,36 @@
void ClassVerifier::verify_exception_handler_targets(u2 bci, bool this_uninit, StackMapFrame* current_frame,
StackMapTable* stackmap_table, TRAPS) {
constantPoolHandle cp (THREAD, _method->constants());
- typeArrayHandle exhandlers (THREAD, _method->exception_table());
- if (exhandlers() != NULL) {
- for(int i = 0; i < exhandlers->length();) {
- u2 start_pc = exhandlers->int_at(i++);
- u2 end_pc = exhandlers->int_at(i++);
- u2 handler_pc = exhandlers->int_at(i++);
- int catch_type_index = exhandlers->int_at(i++);
- if(bci >= start_pc && bci < end_pc) {
- u1 flags = current_frame->flags();
- if (this_uninit) { flags |= FLAG_THIS_UNINIT; }
- StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags);
- if (catch_type_index != 0) {
- // We know that this index refers to a subclass of Throwable
- VerificationType catch_type = cp_index_to_type(
- catch_type_index, cp, CHECK_VERIFY(this));
- new_frame->push_stack(catch_type, CHECK_VERIFY(this));
- } else {
- VerificationType throwable =
- VerificationType::reference_type(vmSymbols::java_lang_Throwable());
- new_frame->push_stack(throwable, CHECK_VERIFY(this));
- }
- bool match = stackmap_table->match_stackmap(
- new_frame, handler_pc, true, false, CHECK_VERIFY(this));
- if (!match) {
- verify_error(bci,
- "Stack map does not match the one at exception handler %d",
- handler_pc);
- return;
- }
+ ExceptionTable exhandlers(_method());
+ int exlength = exhandlers.length();
+ for(int i = 0; i < exlength; i++) {
+ //reacquire the table in case a GC happened
+ ExceptionTable exhandlers(_method());
+ u2 start_pc = exhandlers.start_pc(i);
+ u2 end_pc = exhandlers.end_pc(i);
+ u2 handler_pc = exhandlers.handler_pc(i);
+ int catch_type_index = exhandlers.catch_type_index(i);
+ if(bci >= start_pc && bci < end_pc) {
+ u1 flags = current_frame->flags();
+ if (this_uninit) { flags |= FLAG_THIS_UNINIT; }
+ StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags);
+ if (catch_type_index != 0) {
+ // We know that this index refers to a subclass of Throwable
+ VerificationType catch_type = cp_index_to_type(
+ catch_type_index, cp, CHECK_VERIFY(this));
+ new_frame->push_stack(catch_type, CHECK_VERIFY(this));
+ } else {
+ VerificationType throwable =
+ VerificationType::reference_type(vmSymbols::java_lang_Throwable());
+ new_frame->push_stack(throwable, CHECK_VERIFY(this));
+ }
+ bool match = stackmap_table->match_stackmap(
+ new_frame, handler_pc, true, false, CHECK_VERIFY(this));
+ if (!match) {
+ verify_error(bci,
+ "Stack map does not match the one at exception handler %d",
+ handler_pc);
+ return;
}
}
}
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -375,7 +375,6 @@
Handle h_exception(thread, exception);
methodHandle h_method (thread, method(thread));
constantPoolHandle h_constants(thread, h_method->constants());
- typeArrayHandle h_extable (thread, h_method->exception_table());
bool should_repeat;
int handler_bci;
int current_bci = bci(thread);
--- a/hotspot/src/share/vm/memory/dump.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/memory/dump.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -231,8 +231,6 @@
if (obj->is_constMethod()) {
mark_object(obj);
mark_object(constMethodOop(obj)->stackmap_data());
- // Exception tables are needed by ci code during compilation.
- mark_object(constMethodOop(obj)->exception_table());
}
// Mark objects referenced by klass objects which are read-only.
@@ -513,7 +511,6 @@
for(i = 0; i < methods->length(); i++) {
methodOop m = methodOop(methods->obj_at(i));
mark_and_move_for_policy(OP_favor_startup, m->constMethod(), _move_ro);
- mark_and_move_for_policy(OP_favor_runtime, m->constMethod()->exception_table(), _move_ro);
mark_and_move_for_policy(OP_favor_runtime, m->constMethod()->stackmap_data(), _move_ro);
}
--- a/hotspot/src/share/vm/memory/oopFactory.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/memory/oopFactory.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -140,14 +140,15 @@
constMethodOop oopFactory::new_constMethod(int byte_code_size,
int compressed_line_number_size,
int localvariable_table_length,
+ int exception_table_length,
int checked_exceptions_length,
bool is_conc_safe,
TRAPS) {
klassOop cmkObj = Universe::constMethodKlassObj();
constMethodKlass* cmk = constMethodKlass::cast(cmkObj);
return cmk->allocate(byte_code_size, compressed_line_number_size,
- localvariable_table_length, checked_exceptions_length,
- is_conc_safe,
+ localvariable_table_length, exception_table_length,
+ checked_exceptions_length, is_conc_safe,
CHECK_NULL);
}
@@ -155,6 +156,7 @@
methodOop oopFactory::new_method(int byte_code_size, AccessFlags access_flags,
int compressed_line_number_size,
int localvariable_table_length,
+ int exception_table_length,
int checked_exceptions_length,
bool is_conc_safe,
TRAPS) {
@@ -164,6 +166,7 @@
constMethodOop cm = new_constMethod(byte_code_size,
compressed_line_number_size,
localvariable_table_length,
+ exception_table_length,
checked_exceptions_length,
is_conc_safe, CHECK_NULL);
constMethodHandle rw(THREAD, cm);
--- a/hotspot/src/share/vm/memory/oopFactory.hpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/memory/oopFactory.hpp Tue Jul 17 11:16:13 2012 -0700
@@ -86,6 +86,7 @@
static constMethodOop new_constMethod(int byte_code_size,
int compressed_line_number_size,
int localvariable_table_length,
+ int exception_table_length,
int checked_exceptions_length,
bool is_conc_safe,
TRAPS);
@@ -97,6 +98,7 @@
AccessFlags access_flags,
int compressed_line_number_size,
int localvariable_table_length,
+ int exception_table_length,
int checked_exceptions_length,
bool is_conc_safe,
TRAPS);
--- a/hotspot/src/share/vm/oops/constMethodKlass.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/oops/constMethodKlass.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -65,6 +65,7 @@
constMethodOop constMethodKlass::allocate(int byte_code_size,
int compressed_line_number_size,
int localvariable_table_length,
+ int exception_table_length,
int checked_exceptions_length,
bool is_conc_safe,
TRAPS) {
@@ -72,6 +73,7 @@
int size = constMethodOopDesc::object_size(byte_code_size,
compressed_line_number_size,
localvariable_table_length,
+ exception_table_length,
checked_exceptions_length);
KlassHandle h_k(THREAD, as_klassOop());
constMethodOop cm = (constMethodOop)
@@ -82,12 +84,12 @@
cm->init_fingerprint();
cm->set_constants(NULL);
cm->set_stackmap_data(NULL);
- cm->set_exception_table(NULL);
cm->set_code_size(byte_code_size);
cm->set_constMethod_size(size);
cm->set_inlined_tables_length(checked_exceptions_length,
compressed_line_number_size,
- localvariable_table_length);
+ localvariable_table_length,
+ exception_table_length);
assert(cm->size() == size, "wrong size for object");
cm->set_is_conc_safe(is_conc_safe);
cm->set_partially_loaded();
@@ -100,7 +102,6 @@
constMethodOop cm = constMethodOop(obj);
MarkSweep::mark_and_push(cm->adr_constants());
MarkSweep::mark_and_push(cm->adr_stackmap_data());
- MarkSweep::mark_and_push(cm->adr_exception_table());
// Performance tweak: We skip iterating over the klass pointer since we
// know that Universe::constMethodKlassObj never moves.
}
@@ -112,7 +113,6 @@
constMethodOop cm_oop = constMethodOop(obj);
PSParallelCompact::mark_and_push(cm, cm_oop->adr_constants());
PSParallelCompact::mark_and_push(cm, cm_oop->adr_stackmap_data());
- PSParallelCompact::mark_and_push(cm, cm_oop->adr_exception_table());
// Performance tweak: We skip iterating over the klass pointer since we
// know that Universe::constMethodKlassObj never moves.
}
@@ -123,7 +123,6 @@
constMethodOop cm = constMethodOop(obj);
blk->do_oop(cm->adr_constants());
blk->do_oop(cm->adr_stackmap_data());
- blk->do_oop(cm->adr_exception_table());
// Get size before changing pointers.
// Don't call size() or oop_size() since that is a virtual call.
int size = cm->object_size();
@@ -139,8 +138,6 @@
if (mr.contains(adr)) blk->do_oop(adr);
adr = cm->adr_stackmap_data();
if (mr.contains(adr)) blk->do_oop(adr);
- adr = cm->adr_exception_table();
- if (mr.contains(adr)) blk->do_oop(adr);
// Get size before changing pointers.
// Don't call size() or oop_size() since that is a virtual call.
int size = cm->object_size();
@@ -155,7 +152,6 @@
constMethodOop cm = constMethodOop(obj);
MarkSweep::adjust_pointer(cm->adr_constants());
MarkSweep::adjust_pointer(cm->adr_stackmap_data());
- MarkSweep::adjust_pointer(cm->adr_exception_table());
// Get size before changing pointers.
// Don't call size() or oop_size() since that is a virtual call.
int size = cm->object_size();
@@ -190,7 +186,6 @@
constMethodOop m = constMethodOop(obj);
st->print(" - constants: " INTPTR_FORMAT " ", (address)m->constants());
m->constants()->print_value_on(st); st->cr();
- st->print(" - exceptions: " INTPTR_FORMAT "\n", (address)m->exception_table());
if (m->has_stackmap_table()) {
st->print(" - stackmap data: ");
m->stackmap_data()->print_value_on(st);
@@ -228,8 +223,6 @@
typeArrayOop stackmap_data = m->stackmap_data();
guarantee(stackmap_data == NULL ||
stackmap_data->is_perm(), "should be in permspace");
- guarantee(m->exception_table()->is_perm(), "should be in permspace");
- guarantee(m->exception_table()->is_typeArray(), "should be type array");
address m_end = (address)((oop*) m + m->size());
address compressed_table_start = m->code_end();
@@ -244,11 +237,15 @@
compressed_table_end += stream.position();
}
guarantee(compressed_table_end <= m_end, "invalid method layout");
- // Verify checked exceptions and local variable tables
+ // Verify checked exceptions, exception table and local variable tables
if (m->has_checked_exceptions()) {
u2* addr = m->checked_exceptions_length_addr();
guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
}
+ if (m->has_exception_handler()) {
+ u2* addr = m->exception_table_length_addr();
+ guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
+ }
if (m->has_localvariable_table()) {
u2* addr = m->localvariable_table_length_addr();
guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
@@ -257,12 +254,12 @@
u2* uncompressed_table_start;
if (m->has_localvariable_table()) {
uncompressed_table_start = (u2*) m->localvariable_table_start();
- } else {
- if (m->has_checked_exceptions()) {
+ } else if (m->has_exception_handler()) {
+ uncompressed_table_start = (u2*) m->exception_table_start();
+ } else if (m->has_checked_exceptions()) {
uncompressed_table_start = (u2*) m->checked_exceptions_start();
- } else {
+ } else {
uncompressed_table_start = (u2*) m_end;
- }
}
int gap = (intptr_t) uncompressed_table_start - (intptr_t) compressed_table_end;
int max_gap = align_object_size(1)*BytesPerWord;
@@ -273,8 +270,8 @@
bool constMethodKlass::oop_partially_loaded(oop obj) const {
assert(obj->is_constMethod(), "object must be klass");
constMethodOop m = constMethodOop(obj);
- // check whether exception_table points to self (flag for partially loaded)
- return m->exception_table() == (typeArrayOop)obj;
+ // check whether stackmap_data points to self (flag for partially loaded)
+ return m->stackmap_data() == (typeArrayOop)obj;
}
@@ -282,6 +279,6 @@
void constMethodKlass::oop_set_partially_loaded(oop obj) {
assert(obj->is_constMethod(), "object must be klass");
constMethodOop m = constMethodOop(obj);
- // Temporarily set exception_table to point to self
- m->set_exception_table((typeArrayOop)obj);
+ // Temporarily set stackmap_data to point to self
+ m->set_stackmap_data((typeArrayOop)obj);
}
--- a/hotspot/src/share/vm/oops/constMethodKlass.hpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/oops/constMethodKlass.hpp Tue Jul 17 11:16:13 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,7 @@
DEFINE_ALLOCATE_PERMANENT(constMethodKlass);
constMethodOop allocate(int byte_code_size, int compressed_line_number_size,
int localvariable_table_length,
+ int exception_table_length,
int checked_exceptions_length,
bool is_conc_safe,
TRAPS);
--- a/hotspot/src/share/vm/oops/constMethodOop.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/oops/constMethodOop.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -35,6 +35,7 @@
int constMethodOopDesc::object_size(int code_size,
int compressed_line_number_size,
int local_variable_table_length,
+ int exception_table_length,
int checked_exceptions_length) {
int extra_bytes = code_size;
if (compressed_line_number_size > 0) {
@@ -49,6 +50,10 @@
extra_bytes +=
local_variable_table_length * sizeof(LocalVariableTableElement);
}
+ if (exception_table_length > 0) {
+ extra_bytes += sizeof(u2);
+ extra_bytes += exception_table_length * sizeof(ExceptionTableElement);
+ }
int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
return align_object_size(header_size() + extra_words);
}
@@ -73,23 +78,40 @@
return last_u2_element();
}
-u2* constMethodOopDesc::localvariable_table_length_addr() const {
- assert(has_localvariable_table(), "called only if table is present");
+u2* constMethodOopDesc::exception_table_length_addr() const {
+ assert(has_exception_handler(), "called only if table is present");
if (has_checked_exceptions()) {
// If checked_exception present, locate immediately before them.
return (u2*) checked_exceptions_start() - 1;
} else {
- // Else, the linenumber table is at the end of the constMethod.
+ // Else, the exception table is at the end of the constMethod.
return last_u2_element();
}
}
+u2* constMethodOopDesc::localvariable_table_length_addr() const {
+ assert(has_localvariable_table(), "called only if table is present");
+ if (has_exception_handler()) {
+ // If exception_table present, locate immediately before them.
+ return (u2*) exception_table_start() - 1;
+ } else {
+ if (has_checked_exceptions()) {
+ // If checked_exception present, locate immediately before them.
+ return (u2*) checked_exceptions_start() - 1;
+ } else {
+ // Else, the linenumber table is at the end of the constMethod.
+ return last_u2_element();
+ }
+ }
+}
+
// Update the flags to indicate the presence of these optional fields.
void constMethodOopDesc::set_inlined_tables_length(
int checked_exceptions_len,
int compressed_line_number_size,
- int localvariable_table_len) {
+ int localvariable_table_len,
+ int exception_table_len) {
// Must be done in the order below, otherwise length_addr accessors
// will not work. Only set bit in header if length is positive.
assert(_flags == 0, "Error");
@@ -100,6 +122,10 @@
_flags |= _has_checked_exceptions;
*(checked_exceptions_length_addr()) = checked_exceptions_len;
}
+ if (exception_table_len > 0) {
+ _flags |= _has_exception_table;
+ *(exception_table_length_addr()) = exception_table_len;
+ }
if (localvariable_table_len > 0) {
_flags |= _has_localvariable_table;
*(localvariable_table_length_addr()) = localvariable_table_len;
@@ -133,3 +159,15 @@
addr -= length * sizeof(LocalVariableTableElement) / sizeof(u2);
return (LocalVariableTableElement*) addr;
}
+
+int constMethodOopDesc::exception_table_length() const {
+ return has_exception_handler() ? *(exception_table_length_addr()) : 0;
+}
+
+ExceptionTableElement* constMethodOopDesc::exception_table_start() const {
+ u2* addr = exception_table_length_addr();
+ u2 length = *addr;
+ assert(length > 0, "should only be called if table is present");
+ addr -= length * sizeof(ExceptionTableElement) / sizeof(u2);
+ return (ExceptionTableElement*)addr;
+}
--- a/hotspot/src/share/vm/oops/constMethodOop.hpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/oops/constMethodOop.hpp Tue Jul 17 11:16:13 2012 -0700
@@ -43,7 +43,6 @@
// | fingerprint 2 |
// | constants (oop) |
// | stackmap_data (oop) |
-// | exception_table (oop) |
// | constMethod_size |
// | interp_kind | flags | code_size |
// | name index | signature index |
@@ -64,7 +63,13 @@
// | (length is u2, elements are 6-tuples of u2) |
// | (see class LocalVariableTableElement) |
// | (access flags bit tells whether table is present) |
-// | (indexed from end of contMethodOop) |
+// | (indexed from end of constMethodOop) |
+// |------------------------------------------------------|
+// | exception table + length (length last) |
+// | (length is u2, elements are 4-tuples of u2) |
+// | (see class ExceptionTableElement) |
+// | (access flags bit tells whether table is present) |
+// | (indexed from end of constMethodOop) |
// |------------------------------------------------------|
// | checked exceptions elements + length (length last) |
// | (length is u2, elements are u2) |
@@ -93,6 +98,15 @@
};
+// Utitily class describing elements in exception table
+class ExceptionTableElement VALUE_OBJ_CLASS_SPEC {
+ public:
+ u2 start_pc;
+ u2 end_pc;
+ u2 handler_pc;
+ u2 catch_type_index;
+};
+
class constMethodOopDesc : public oopDesc {
friend class constMethodKlass;
friend class VMStructs;
@@ -100,7 +114,8 @@
enum {
_has_linenumber_table = 1,
_has_checked_exceptions = 2,
- _has_localvariable_table = 4
+ _has_localvariable_table = 4,
+ _has_exception_table = 8
};
// Bit vector of signature
@@ -114,7 +129,7 @@
public:
oop* oop_block_beg() const { return adr_constants(); }
- oop* oop_block_end() const { return adr_exception_table() + 1; }
+ oop* oop_block_end() const { return adr_stackmap_data() + 1; }
private:
//
@@ -126,11 +141,6 @@
// Raw stackmap data for the method
typeArrayOop _stackmap_data;
- // The exception handler table. 4-tuples of ints [start_pc, end_pc,
- // handler_pc, catch_type index] For methods with no exceptions the
- // table is pointing to Universe::the_empty_int_array
- typeArrayOop _exception_table;
-
//
// End of the oop block.
//
@@ -152,7 +162,8 @@
// Inlined tables
void set_inlined_tables_length(int checked_exceptions_len,
int compressed_line_number_size,
- int localvariable_table_len);
+ int localvariable_table_len,
+ int exception_table_len);
bool has_linenumber_table() const
{ return (_flags & _has_linenumber_table) != 0; }
@@ -163,6 +174,9 @@
bool has_localvariable_table() const
{ return (_flags & _has_localvariable_table) != 0; }
+ bool has_exception_handler() const
+ { return (_flags & _has_exception_table) != 0; }
+
void set_interpreter_kind(int kind) { _interpreter_kind = kind; }
int interpreter_kind(void) const { return _interpreter_kind; }
@@ -181,11 +195,6 @@
}
bool has_stackmap_table() const { return _stackmap_data != NULL; }
- // exception handler table
- typeArrayOop exception_table() const { return _exception_table; }
- void set_exception_table(typeArrayOop e) { oop_store_without_check((oop*) &_exception_table, (oop) e); }
- bool has_exception_handler() const { return exception_table() != NULL && exception_table()->length() > 0; }
-
void init_fingerprint() {
const uint64_t initval = CONST64(0x8000000000000000);
_fingerprint = initval;
@@ -235,6 +244,7 @@
// Object size needed
static int object_size(int code_size, int compressed_line_number_size,
int local_variable_table_length,
+ int exception_table_length,
int checked_exceptions_length);
int object_size() const { return _constMethod_size; }
@@ -256,6 +266,7 @@
u_char* compressed_linenumber_table() const; // not preserved by gc
u2* checked_exceptions_length_addr() const;
u2* localvariable_table_length_addr() const;
+ u2* exception_table_length_addr() const;
// checked exceptions
int checked_exceptions_length() const;
@@ -265,6 +276,10 @@
int localvariable_table_length() const;
LocalVariableTableElement* localvariable_table_start() const;
+ // exception table
+ int exception_table_length() const;
+ ExceptionTableElement* exception_table_start() const;
+
// byte codes
void set_code(address code) {
if (code_size() > 0) {
@@ -282,13 +297,10 @@
// interpreter support
static ByteSize constants_offset()
{ return byte_offset_of(constMethodOopDesc, _constants); }
- static ByteSize exception_table_offset()
- { return byte_offset_of(constMethodOopDesc, _exception_table); }
// Garbage collection support
oop* adr_constants() const { return (oop*)&_constants; }
oop* adr_stackmap_data() const { return (oop*)&_stackmap_data; }
- oop* adr_exception_table() const { return (oop*)&_exception_table; }
bool is_conc_safe() { return _is_conc_safe; }
void set_is_conc_safe(bool v) { _is_conc_safe = v; }
--- a/hotspot/src/share/vm/oops/generateOopMap.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/oops/generateOopMap.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -400,10 +400,9 @@
bool fellThrough = false; // False to get first BB marked.
// First mark all exception handlers as start of a basic-block
- typeArrayOop excps = method()->exception_table();
- for(int i = 0; i < excps->length(); i += 4) {
- int handler_pc_idx = i+2;
- bb_mark_fct(this, excps->int_at(handler_pc_idx), NULL);
+ ExceptionTable excps(method());
+ for(int i = 0; i < excps.length(); i ++) {
+ bb_mark_fct(this, excps.handler_pc(i), NULL);
}
// Then iterate through the code
@@ -450,10 +449,9 @@
// Mark entry basic block as alive and all exception handlers
_basic_blocks[0].mark_as_alive();
- typeArrayOop excps = method()->exception_table();
- for(int i = 0; i < excps->length(); i += 4) {
- int handler_pc_idx = i+2;
- BasicBlock *bb = get_basic_block_at(excps->int_at(handler_pc_idx));
+ ExceptionTable excps(method());
+ for(int i = 0; i < excps.length(); i++) {
+ BasicBlock *bb = get_basic_block_at(excps.handler_pc(i));
// If block is not already alive (due to multiple exception handlers to same bb), then
// make it alive
if (bb->is_dead()) bb->mark_as_alive();
@@ -1181,12 +1179,12 @@
if (_has_exceptions) {
int bci = itr->bci();
- typeArrayOop exct = method()->exception_table();
- for(int i = 0; i< exct->length(); i+=4) {
- int start_pc = exct->int_at(i);
- int end_pc = exct->int_at(i+1);
- int handler_pc = exct->int_at(i+2);
- int catch_type = exct->int_at(i+3);
+ ExceptionTable exct(method());
+ for(int i = 0; i< exct.length(); i++) {
+ int start_pc = exct.start_pc(i);
+ int end_pc = exct.end_pc(i);
+ int handler_pc = exct.handler_pc(i);
+ int catch_type = exct.catch_type_index(i);
if (start_pc <= bci && bci < end_pc) {
BasicBlock *excBB = get_basic_block_at(handler_pc);
@@ -2055,7 +2053,7 @@
_conflict = false;
_max_locals = method()->max_locals();
_max_stack = method()->max_stack();
- _has_exceptions = (method()->exception_table()->length() > 0);
+ _has_exceptions = (method()->has_exception_handler());
_nof_refval_conflicts = 0;
_init_vars = new GrowableArray<intptr_t>(5); // There are seldom more than 5 init_vars
_report_result = false;
@@ -2070,9 +2068,10 @@
if (Verbose) {
_method->print_codes();
tty->print_cr("Exception table:");
- typeArrayOop excps = method()->exception_table();
- for(int i = 0; i < excps->length(); i += 4) {
- tty->print_cr("[%d - %d] -> %d", excps->int_at(i + 0), excps->int_at(i + 1), excps->int_at(i + 2));
+ ExceptionTable excps(method());
+ for(int i = 0; i < excps.length(); i ++) {
+ tty->print_cr("[%d - %d] -> %d",
+ excps.start_pc(i), excps.end_pc(i), excps.handler_pc(i));
}
}
}
--- a/hotspot/src/share/vm/oops/methodOop.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/oops/methodOop.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -111,25 +111,21 @@
int methodOopDesc::fast_exception_handler_bci_for(KlassHandle ex_klass, int throw_bci, TRAPS) {
// exception table holds quadruple entries of the form (beg_bci, end_bci, handler_bci, klass_index)
- const int beg_bci_offset = 0;
- const int end_bci_offset = 1;
- const int handler_bci_offset = 2;
- const int klass_index_offset = 3;
- const int entry_size = 4;
// access exception table
- typeArrayHandle table (THREAD, constMethod()->exception_table());
- int length = table->length();
- assert(length % entry_size == 0, "exception table format has changed");
+ ExceptionTable table(this);
+ int length = table.length();
// iterate through all entries sequentially
constantPoolHandle pool(THREAD, constants());
- for (int i = 0; i < length; i += entry_size) {
- int beg_bci = table->int_at(i + beg_bci_offset);
- int end_bci = table->int_at(i + end_bci_offset);
+ for (int i = 0; i < length; i ++) {
+ //reacquire the table in case a GC happened
+ ExceptionTable table(this);
+ int beg_bci = table.start_pc(i);
+ int end_bci = table.end_pc(i);
assert(beg_bci <= end_bci, "inconsistent exception table");
if (beg_bci <= throw_bci && throw_bci < end_bci) {
// exception handler bci range covers throw_bci => investigate further
- int handler_bci = table->int_at(i + handler_bci_offset);
- int klass_index = table->int_at(i + klass_index_offset);
+ int handler_bci = table.handler_pc(i);
+ int klass_index = table.catch_type_index(i);
if (klass_index == 0) {
return handler_bci;
} else if (ex_klass.is_null()) {
@@ -980,7 +976,7 @@
{
int flags_bits = (JVM_MH_INVOKE_BITS | JVM_ACC_PUBLIC | JVM_ACC_FINAL);
methodOop m_oop = oopFactory::new_method(0, accessFlags_from(flags_bits),
- 0, 0, 0, IsSafeConc, CHECK_(empty));
+ 0, 0, 0, 0, IsSafeConc, CHECK_(empty));
m = methodHandle(THREAD, m_oop);
}
m->set_constants(cp());
@@ -994,7 +990,6 @@
m->set_result_index(rtf.type());
#endif
m->compute_size_of_parameters(THREAD);
- m->set_exception_table(Universe::the_empty_int_array());
m->init_intrinsic_id();
assert(m->intrinsic_id() == vmIntrinsics::_invokeExact ||
m->intrinsic_id() == vmIntrinsics::_invokeGeneric, "must be an invoker");
@@ -1038,6 +1033,7 @@
AccessFlags flags = m->access_flags();
int checked_exceptions_len = m->checked_exceptions_length();
int localvariable_len = m->localvariable_table_length();
+ int exception_table_len = m->exception_table_length();
// Allocate newm_oop with the is_conc_safe parameter set
// to IsUnsafeConc to indicate that newm_oop is not yet
// safe for concurrent processing by a GC.
@@ -1045,6 +1041,7 @@
flags,
new_compressed_linenumber_size,
localvariable_len,
+ exception_table_len,
checked_exceptions_len,
IsUnsafeConc,
CHECK_(methodHandle()));
@@ -1085,6 +1082,7 @@
newm->set_method_size(new_method_size);
assert(newm->code_size() == new_code_length, "check");
assert(newm->checked_exceptions_length() == checked_exceptions_len, "check");
+ assert(newm->exception_table_length() == exception_table_len, "check");
assert(newm->localvariable_table_length() == localvariable_len, "check");
// Copy new byte codes
memcpy(newm->code_base(), new_code, new_code_length);
@@ -1100,6 +1098,12 @@
m->checked_exceptions_start(),
checked_exceptions_len * sizeof(CheckedExceptionElement));
}
+ // Copy exception table
+ if (exception_table_len > 0) {
+ memcpy(newm->exception_table_start(),
+ m->exception_table_start(),
+ exception_table_len * sizeof(ExceptionTableElement));
+ }
// Copy local variable number table
if (localvariable_len > 0) {
memcpy(newm->localvariable_table_start(),
--- a/hotspot/src/share/vm/oops/methodOop.hpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/oops/methodOop.hpp Tue Jul 17 11:16:13 2012 -0700
@@ -283,12 +283,12 @@
}
// exception handler table
- typeArrayOop exception_table() const
- { return constMethod()->exception_table(); }
- void set_exception_table(typeArrayOop e)
- { constMethod()->set_exception_table(e); }
bool has_exception_handler() const
{ return constMethod()->has_exception_handler(); }
+ int exception_table_length() const
+ { return constMethod()->exception_table_length(); }
+ ExceptionTableElement* exception_table_start() const
+ { return constMethod()->exception_table_start(); }
// Finds the first entry point bci of an exception handler for an
// exception of klass ex_klass thrown at throw_bci. A value of NULL
@@ -839,4 +839,66 @@
void clear(methodOop method);
};
+// Utility class for access exception handlers
+class ExceptionTable : public StackObj {
+ private:
+ ExceptionTableElement* _table;
+ u2 _length;
+
+ public:
+ ExceptionTable(methodOop m) {
+ if (m->has_exception_handler()) {
+ _table = m->exception_table_start();
+ _length = m->exception_table_length();
+ } else {
+ _table = NULL;
+ _length = 0;
+ }
+ }
+
+ int length() const {
+ return _length;
+ }
+
+ u2 start_pc(int idx) const {
+ assert(idx < _length, "out of bounds");
+ return _table[idx].start_pc;
+ }
+
+ void set_start_pc(int idx, u2 value) {
+ assert(idx < _length, "out of bounds");
+ _table[idx].start_pc = value;
+ }
+
+ u2 end_pc(int idx) const {
+ assert(idx < _length, "out of bounds");
+ return _table[idx].end_pc;
+ }
+
+ void set_end_pc(int idx, u2 value) {
+ assert(idx < _length, "out of bounds");
+ _table[idx].end_pc = value;
+ }
+
+ u2 handler_pc(int idx) const {
+ assert(idx < _length, "out of bounds");
+ return _table[idx].handler_pc;
+ }
+
+ void set_handler_pc(int idx, u2 value) {
+ assert(idx < _length, "out of bounds");
+ _table[idx].handler_pc = value;
+ }
+
+ u2 catch_type_index(int idx) const {
+ assert(idx < _length, "out of bounds");
+ return _table[idx].catch_type_index;
+ }
+
+ void set_catch_type_index(int idx, u2 value) {
+ assert(idx < _length, "out of bounds");
+ _table[idx].catch_type_index = value;
+ }
+};
+
#endif // SHARE_VM_OOPS_METHODOOP_HPP
--- a/hotspot/src/share/vm/prims/jvm.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -35,6 +35,7 @@
#include "oops/fieldStreams.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/objArrayKlass.hpp"
+#include "oops/methodOop.hpp"
#include "prims/jvm.h"
#include "prims/jvm_misc.hpp"
#include "prims/jvmtiExport.hpp"
@@ -2183,11 +2184,11 @@
klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls));
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
oop method = instanceKlass::cast(k)->methods()->obj_at(method_index);
- typeArrayOop extable = methodOop(method)->exception_table();
- entry->start_pc = extable->int_at(entry_index * 4);
- entry->end_pc = extable->int_at(entry_index * 4 + 1);
- entry->handler_pc = extable->int_at(entry_index * 4 + 2);
- entry->catchType = extable->int_at(entry_index * 4 + 3);
+ ExceptionTable extable((methodOop(method)));
+ entry->start_pc = extable.start_pc(entry_index);
+ entry->end_pc = extable.end_pc(entry_index);
+ entry->handler_pc = extable.handler_pc(entry_index);
+ entry->catchType = extable.catch_type_index(entry_index);
JVM_END
@@ -2196,7 +2197,7 @@
klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls));
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
oop method = instanceKlass::cast(k)->methods()->obj_at(method_index);
- return methodOop(method)->exception_table()->length() / 4;
+ return methodOop(method)->exception_table_length();
JVM_END
--- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -191,15 +191,14 @@
}
}
- typeArrayHandle exception_table(thread(), const_method->exception_table());
- int exception_table_length = exception_table->length();
- int exception_table_entries = exception_table_length / 4;
+ ExceptionTable exception_table(method());
+ int exception_table_length = exception_table.length();
int code_size = const_method->code_size();
int size =
2+2+4 + // max_stack, max_locals, code_length
code_size + // code
2 + // exception_table_length
- (2+2+2+2) * exception_table_entries + // exception_table
+ (2+2+2+2) * exception_table_length + // exception_table
2 + // attributes_count
attr_size; // attributes
@@ -209,12 +208,12 @@
write_u2(method->max_locals());
write_u4(code_size);
copy_bytecodes(method, (unsigned char*)writeable_address(code_size));
- write_u2(exception_table_entries);
- for (int index = 0; index < exception_table_length; ) {
- write_u2(exception_table->int_at(index++));
- write_u2(exception_table->int_at(index++));
- write_u2(exception_table->int_at(index++));
- write_u2(exception_table->int_at(index++));
+ write_u2(exception_table_length);
+ for (int index = 0; index < exception_table_length; index++) {
+ write_u2(exception_table.start_pc(index));
+ write_u2(exception_table.end_pc(index));
+ write_u2(exception_table.handler_pc(index));
+ write_u2(exception_table.catch_type_index(index));
}
write_u2(attr_count);
if (line_num_cnt != 0) {
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -2478,23 +2478,17 @@
// to use new constant pool indices as needed. The exception table
// holds quadruple entries of the form:
// (beg_bci, end_bci, handler_bci, klass_index)
- const int beg_bci_offset = 0;
- const int end_bci_offset = 1;
- const int handler_bci_offset = 2;
- const int klass_index_offset = 3;
- const int entry_size = 4;
-
- typeArrayHandle ex_table (THREAD, method->exception_table());
- int ext_length = ex_table->length();
- assert(ext_length % entry_size == 0, "exception table format has changed");
-
- for (int j = 0; j < ext_length; j += entry_size) {
- int cur_index = ex_table->int_at(j + klass_index_offset);
+
+ ExceptionTable ex_table(method());
+ int ext_length = ex_table.length();
+
+ for (int j = 0; j < ext_length; j ++) {
+ int cur_index = ex_table.catch_type_index(j);
int new_index = find_new_index(cur_index);
if (new_index != 0) {
RC_TRACE_WITH_THREAD(0x00080000, THREAD,
("ext-klass_index change: %d to %d", cur_index, new_index));
- ex_table->int_at_put(j + klass_index_offset, new_index);
+ ex_table.set_catch_type_index(j, new_index);
}
} // end for each exception table entry
--- a/hotspot/src/share/vm/prims/methodHandleWalk.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/prims/methodHandleWalk.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1796,7 +1796,7 @@
{
methodOop m_oop = oopFactory::new_method(bytecode_length(),
accessFlags_from(flags_bits),
- 0, 0, 0, oopDesc::IsSafeConc, CHECK_(empty));
+ 0, 0, 0, 0, oopDesc::IsSafeConc, CHECK_(empty));
m = methodHandle(THREAD, m_oop);
}
@@ -1812,9 +1812,6 @@
m->set_max_locals(max_locals());
m->set_size_of_parameters(_num_params);
- typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array());
- m->set_exception_table(exception_handlers());
-
// Rewrite the method and set up the constant pool cache.
objArrayOop m_array = oopFactory::new_system_objArray(1, CHECK_(empty));
objArrayHandle methods(THREAD, m_array);
--- a/hotspot/src/share/vm/runtime/relocator.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/runtime/relocator.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -392,16 +392,16 @@
// The width of instruction at "pc" is changing by "delta". Adjust the
// exception table, if any, of "rc->mb".
void Relocator::adjust_exception_table(int bci, int delta) {
- typeArrayOop table = method()->exception_table();
- for (int index = 0; index < table->length(); index +=4) {
- if (table->int_at(index) > bci) {
- table->int_at_put(index+0, table->int_at(index+0) + delta);
- table->int_at_put(index+1, table->int_at(index+1) + delta);
- } else if (bci < table->int_at(index+1)) {
- table->int_at_put(index+1, table->int_at(index+1) + delta);
+ ExceptionTable table(_method());
+ for (int index = 0; index < table.length(); index ++) {
+ if (table.start_pc(index) > bci) {
+ table.set_start_pc(index, table.start_pc(index) + delta);
+ table.set_end_pc(index, table.end_pc(index) + delta);
+ } else if (bci < table.end_pc(index)) {
+ table.set_end_pc(index, table.end_pc(index) + delta);
}
- if (table->int_at(index+2) > bci)
- table->int_at_put(index+2, table->int_at(index+2) + delta);
+ if (table.handler_pc(index) > bci)
+ table.set_handler_pc(index, table.handler_pc(index) + delta);
}
}
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Mon Jul 16 19:50:52 2012 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Tue Jul 17 11:16:13 2012 -0700
@@ -388,7 +388,6 @@
volatile_nonstatic_field(constMethodOopDesc, _fingerprint, uint64_t) \
nonstatic_field(constMethodOopDesc, _constants, constantPoolOop) \
nonstatic_field(constMethodOopDesc, _stackmap_data, typeArrayOop) \
- nonstatic_field(constMethodOopDesc, _exception_table, typeArrayOop) \
nonstatic_field(constMethodOopDesc, _constMethod_size, int) \
nonstatic_field(constMethodOopDesc, _interpreter_kind, jbyte) \
nonstatic_field(constMethodOopDesc, _flags, jbyte) \
@@ -425,6 +424,10 @@
nonstatic_field(LocalVariableTableElement, descriptor_cp_index, u2) \
nonstatic_field(LocalVariableTableElement, signature_cp_index, u2) \
nonstatic_field(LocalVariableTableElement, slot, u2) \
+ nonstatic_field(ExceptionTableElement, start_pc, u2) \
+ nonstatic_field(ExceptionTableElement, end_pc, u2) \
+ nonstatic_field(ExceptionTableElement, handler_pc, u2) \
+ nonstatic_field(ExceptionTableElement, catch_type_index, u2) \
nonstatic_field(BreakpointInfo, _orig_bytecode, Bytecodes::Code) \
nonstatic_field(BreakpointInfo, _bci, int) \
nonstatic_field(BreakpointInfo, _name_index, u2) \
@@ -1460,6 +1463,7 @@
\
declare_toplevel_type(CheckedExceptionElement) \
declare_toplevel_type(LocalVariableTableElement) \
+ declare_toplevel_type(ExceptionTableElement) \
\
/******************************************/ \
/* Generation and space hierarchies */ \
@@ -2301,6 +2305,7 @@
declare_constant(constMethodOopDesc::_has_linenumber_table) \
declare_constant(constMethodOopDesc::_has_checked_exceptions) \
declare_constant(constMethodOopDesc::_has_localvariable_table) \
+ declare_constant(constMethodOopDesc::_has_exception_table) \
\
/*************************************/ \
/* instanceKlass enum */ \