Merge
This commit is contained in:
commit
3a878bffe5
@ -654,8 +654,8 @@ class Attribute implements Comparable, Constants {
|
||||
String layout;
|
||||
public FormatException(String message,
|
||||
int ctype, String name, String layout) {
|
||||
super(ATTR_CONTEXT_NAME[ctype]+"."+name
|
||||
+(message == null? "": (": "+message)));
|
||||
super(ATTR_CONTEXT_NAME[ctype]+ " attribute \"" + name + "\"" +
|
||||
(message == null? "" : (": " + message)));
|
||||
this.ctype = ctype;
|
||||
this.name = name;
|
||||
this.layout = layout;
|
||||
|
@ -30,6 +30,7 @@ import java.util.*;
|
||||
import com.sun.java.util.jar.pack.Package.Class;
|
||||
import com.sun.java.util.jar.pack.Package.InnerClass;
|
||||
import com.sun.java.util.jar.pack.ConstantPool.*;
|
||||
import com.sun.tools.classfile.AttributeException;
|
||||
|
||||
/**
|
||||
* Reader for a class file that is being incorporated into a package.
|
||||
@ -246,7 +247,9 @@ class ClassReader implements Constants {
|
||||
fixups[fptr++] = in.readUnsignedShort();
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Bad constant pool tag "+tag);
|
||||
throw new ClassFormatException("Bad constant pool tag " +
|
||||
tag + " in File: " + cls.file.nameString +
|
||||
" at pos: " + inPos);
|
||||
}
|
||||
}
|
||||
|
||||
@ -403,7 +406,7 @@ class ClassReader implements Constants {
|
||||
skip(length, "unknown "+name+" attribute in "+h);
|
||||
continue;
|
||||
} else {
|
||||
String message = "unknown in "+h;
|
||||
String message = " is unknown attribute in class " + h;
|
||||
throw new Attribute.FormatException(message, ctype, name,
|
||||
unknownAttrCommand);
|
||||
}
|
||||
@ -415,7 +418,12 @@ class ClassReader implements Constants {
|
||||
if (a.name() == "Code") {
|
||||
Class.Method m = (Class.Method) h;
|
||||
m.code = new Code(m);
|
||||
readCode(m.code);
|
||||
try {
|
||||
readCode(m.code);
|
||||
} catch (Instruction.FormatException iie) {
|
||||
String message = iie.getMessage() + " in " + h;
|
||||
throw new ClassReader.ClassFormatException(message);
|
||||
}
|
||||
} else {
|
||||
assert(h == cls);
|
||||
readInnerClasses(cls);
|
||||
@ -427,6 +435,10 @@ class ClassReader implements Constants {
|
||||
in.readFully(bytes);
|
||||
a = a.addContent(bytes);
|
||||
}
|
||||
if (a.size() == 0 && !a.layout().isEmpty()) {
|
||||
throw new ClassFormatException(name +
|
||||
": attribute length cannot be zero, in " + h);
|
||||
}
|
||||
h.addAttribute(a);
|
||||
if (verbose > 2)
|
||||
Utils.log.fine("read "+a);
|
||||
@ -438,6 +450,7 @@ class ClassReader implements Constants {
|
||||
code.max_locals = readUnsignedShort();
|
||||
code.bytes = new byte[readInt()];
|
||||
in.readFully(code.bytes);
|
||||
Instruction.opcodeChecker(code.bytes);
|
||||
int nh = readUnsignedShort();
|
||||
code.setHandlerCount(nh);
|
||||
for (int i = 0; i < nh; i++) {
|
||||
@ -463,4 +476,10 @@ class ClassReader implements Constants {
|
||||
cls.innerClasses = ics; // set directly; do not use setInnerClasses.
|
||||
// (Later, ics may be transferred to the pkg.)
|
||||
}
|
||||
|
||||
class ClassFormatException extends IOException {
|
||||
public ClassFormatException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
package com.sun.java.util.jar.pack;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A parsed bytecode instruction.
|
||||
* Provides accessors to various relevant bits.
|
||||
@ -628,4 +630,21 @@ class Instruction implements Constants {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void opcodeChecker(byte[] code) throws FormatException {
|
||||
Instruction i = at(code, 0);
|
||||
while (i != null) {
|
||||
int opcode = i.getBC();
|
||||
if (opcode == _xxxunusedxxx || opcode < _nop || opcode > _jsr_w) {
|
||||
String message = "illegal opcode: " + opcode + " " + i;
|
||||
throw new FormatException(message);
|
||||
}
|
||||
i = i.next();
|
||||
}
|
||||
}
|
||||
static class FormatException extends IOException {
|
||||
FormatException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -496,15 +496,29 @@ public class PackerImpl extends TLGlobals implements Pack200.Packer {
|
||||
reader.unknownAttrCommand = unknownAttrCommand;
|
||||
try {
|
||||
reader.read();
|
||||
} catch (Attribute.FormatException ee) {
|
||||
// He passed up the category to us in layout.
|
||||
if (ee.layout.equals(Pack200.Packer.PASS)) {
|
||||
Utils.log.warning("Passing class file uncompressed due to unrecognized attribute: "+fname);
|
||||
Utils.log.info(ee.toString());
|
||||
return null;
|
||||
} catch (IOException ioe) {
|
||||
String message = "Passing class file uncompressed due to";
|
||||
if (ioe instanceof Attribute.FormatException) {
|
||||
Attribute.FormatException ee = (Attribute.FormatException) ioe;
|
||||
// He passed up the category to us in layout.
|
||||
if (ee.layout.equals(Pack200.Packer.PASS)) {
|
||||
Utils.log.info(ee.toString());
|
||||
Utils.log.warning(message + " unrecognized attribute: " +
|
||||
fname);
|
||||
return null;
|
||||
}
|
||||
} else if (ioe instanceof ClassReader.ClassFormatException) {
|
||||
ClassReader.ClassFormatException ce = (ClassReader.ClassFormatException) ioe;
|
||||
// %% TODO: Do we invent a new property for this or reuse %%
|
||||
if (unknownAttrCommand.equals(Pack200.Packer.PASS)) {
|
||||
Utils.log.info(ce.toString());
|
||||
Utils.log.warning(message + " unknown class format: " +
|
||||
fname);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// Otherwise, it must be an error.
|
||||
throw ee;
|
||||
throw ioe;
|
||||
}
|
||||
pkg.addClass(cls);
|
||||
return cls.file;
|
||||
|
@ -182,11 +182,8 @@ class Utils {
|
||||
}
|
||||
|
||||
public void warning(String msg, Object param) {
|
||||
int verbose = currentPropMap().getInteger(DEBUG_VERBOSE);
|
||||
if (verbose > 0) {
|
||||
getLogger().warning(msg, param);
|
||||
}
|
||||
}
|
||||
|
||||
public void warning(String msg) {
|
||||
warning(msg, null);
|
||||
|
@ -29,6 +29,7 @@ package java.nio;
|
||||
|
||||
import sun.misc.Cleaner;
|
||||
import sun.misc.Unsafe;
|
||||
import sun.misc.VM;
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
|
||||
|
||||
@ -114,8 +115,9 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
Direct$Type$Buffer$RW$(int cap) { // package-private
|
||||
#if[rw]
|
||||
super(-1, 0, cap, cap, false);
|
||||
boolean pa = VM.isDirectMemoryPageAligned();
|
||||
int ps = Bits.pageSize();
|
||||
int size = cap + ps;
|
||||
long size = Math.max(1L, (long)cap + (pa ? ps : 0));
|
||||
Bits.reserveMemory(size, cap);
|
||||
|
||||
long base = 0;
|
||||
@ -126,7 +128,7 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
throw x;
|
||||
}
|
||||
unsafe.setMemory(base, size, (byte) 0);
|
||||
if (base % ps != 0) {
|
||||
if (pa && (base % ps != 0)) {
|
||||
// Round up to page boundary
|
||||
address = base + ps - (base & (ps - 1));
|
||||
} else {
|
||||
|
@ -178,6 +178,17 @@ public class VM {
|
||||
return directMemory;
|
||||
}
|
||||
|
||||
// User-controllable flag that determines if direct buffers should be page
|
||||
// aligned. The "-XX:+PageAlignDirectMemory" option can be used to force
|
||||
// buffers, allocated by ByteBuffer.allocateDirect, to be page aligned.
|
||||
private static boolean pageAlignDirectMemory;
|
||||
|
||||
// Returns {@code true} if the direct buffers should be page aligned. This
|
||||
// variable is initialized by saveAndRemoveProperties.
|
||||
public static boolean isDirectMemoryPageAligned() {
|
||||
return pageAlignDirectMemory;
|
||||
}
|
||||
|
||||
// A user-settable boolean to determine whether ClassLoader.loadClass should
|
||||
// accept array syntax. This value may be changed during VM initialization
|
||||
// via the system property "sun.lang.ClassLoader.allowArraySyntax".
|
||||
@ -252,6 +263,11 @@ public class VM {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if direct buffers should be page aligned
|
||||
s = (String)props.remove("sun.nio.PageAlignDirectMemory");
|
||||
if ("true".equals(s))
|
||||
pageAlignDirectMemory = true;
|
||||
|
||||
// Set a boolean to determine whether ClassLoader.loadClass accepts
|
||||
// array syntax. This value is controlled by the system property
|
||||
// "sun.lang.ClassLoader.allowArraySyntax".
|
||||
|
@ -30,18 +30,7 @@
|
||||
# @build LimitDirectMemory
|
||||
# @run shell LimitDirectMemory.sh
|
||||
|
||||
# set platform-dependent variable
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux ) TMP=/tmp ;;
|
||||
Windows* ) TMP="c:/temp" ;;
|
||||
* )
|
||||
echo "Unrecognized system!"
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
||||
|
||||
TMP1=${TMP}/tmp1_$$
|
||||
TMP1=tmp_$$
|
||||
|
||||
runTest() {
|
||||
echo "Testing: $*"
|
||||
@ -82,18 +71,21 @@ runTest -XX:MaxDirectMemorySize=65M -cp ${TESTCLASSES} \
|
||||
|
||||
# Exactly the default amount of memory is available.
|
||||
runTest -cp ${TESTCLASSES} LimitDirectMemory false 10 1
|
||||
runTest -cp ${TESTCLASSES} LimitDirectMemory false 0 DEFAULT
|
||||
runTest -cp ${TESTCLASSES} LimitDirectMemory true 0 DEFAULT+1
|
||||
runTest -Xmx64m -cp ${TESTCLASSES} LimitDirectMemory false 0 DEFAULT
|
||||
runTest -Xmx64m -cp ${TESTCLASSES} LimitDirectMemory true 0 DEFAULT+1
|
||||
|
||||
# We should be able to eliminate direct memory allocation entirely.
|
||||
runTest -XX:MaxDirectMemorySize=0 -cp ${TESTCLASSES} LimitDirectMemory true 0 1
|
||||
|
||||
# Setting the system property should not work so we should be able to allocate
|
||||
# the default amount.
|
||||
runTest -Dsun.nio.MaxDirectMemorySize=1K -cp ${TESTCLASSES} \
|
||||
runTest -Dsun.nio.MaxDirectMemorySize=1K -Xmx64m -cp ${TESTCLASSES} \
|
||||
LimitDirectMemory false DEFAULT-1 DEFAULT/2
|
||||
|
||||
# Various bad values fail to launch the VM.
|
||||
launchFail foo
|
||||
launchFail 10kmt
|
||||
launchFail -1
|
||||
|
||||
# Clean-up
|
||||
rm ${TMP1}
|
||||
|
131
jdk/test/tools/pack200/AttributeTests.java
Normal file
131
jdk/test/tools/pack200/AttributeTests.java
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 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.
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
/*
|
||||
* @test
|
||||
* @bug 6982312
|
||||
* @summary tests various classfile format and attribute handling by pack200
|
||||
* @compile -XDignore.symbol.file Utils.java AttributeTests.java
|
||||
* @run main AttributeTests
|
||||
* @author ksrini
|
||||
*/
|
||||
public class AttributeTests {
|
||||
|
||||
public static void main(String... args) throws Exception {
|
||||
test6982312();
|
||||
test6746111();
|
||||
}
|
||||
/*
|
||||
* This is an interim test, which ensures pack200 handles JSR-292 related
|
||||
* classfile changes seamlessly, until all the classfile changes in jdk7
|
||||
* and jdk8 are fully supported. At that time this test should be jettisoned,
|
||||
* along with the associated jar file.
|
||||
*
|
||||
* The jar file contains sources and classes noting the classes were
|
||||
* derived by using the javac from the lambda project,
|
||||
* see http://openjdk.java.net/projects/lambda/.
|
||||
* Therefore the classes contained in the jar cannot be compiled, using
|
||||
* the standard jdk7's javac compiler.
|
||||
*/
|
||||
static void test6982312() throws IOException {
|
||||
String pack200Cmd = Utils.getPack200Cmd();
|
||||
File dynJar = new File(".", "dyn.jar");
|
||||
Utils.copyFile(new File(Utils.TEST_SRC_DIR, "dyn.jar"), dynJar);
|
||||
File testJar = new File(".", "test.jar");
|
||||
List<String> cmds = new ArrayList<String>();
|
||||
cmds.add(pack200Cmd);
|
||||
cmds.add("--repack");
|
||||
cmds.add(testJar.getAbsolutePath());
|
||||
cmds.add(dynJar.getAbsolutePath());
|
||||
Utils.runExec(cmds);
|
||||
/*
|
||||
* compare the repacked jar bit-wise, as all the files
|
||||
* should be transmitted "as-is".
|
||||
*/
|
||||
Utils.doCompareBitWise(dynJar.getAbsoluteFile(), testJar.getAbsoluteFile());
|
||||
testJar.delete();
|
||||
dynJar.delete();
|
||||
}
|
||||
|
||||
/*
|
||||
* this test checks to see if we get the expected strings for output
|
||||
*/
|
||||
static void test6746111() throws Exception {
|
||||
String pack200Cmd = Utils.getPack200Cmd();
|
||||
File badAttrJar = new File(".", "badattr.jar");
|
||||
Utils.copyFile(new File(Utils.TEST_SRC_DIR, "badattr.jar"), badAttrJar);
|
||||
File testJar = new File(".", "test.jar");
|
||||
List<String> cmds = new ArrayList<String>();
|
||||
cmds.add(pack200Cmd);
|
||||
cmds.add("--repack");
|
||||
cmds.add("-v");
|
||||
cmds.add(testJar.getAbsolutePath());
|
||||
cmds.add(badAttrJar.getAbsolutePath());
|
||||
List<String> output = Utils.runExec(cmds);
|
||||
/*
|
||||
* compare the repacked jar bit-wise, as all the files
|
||||
* should be transmitted "as-is".
|
||||
*/
|
||||
Utils.doCompareBitWise(badAttrJar.getAbsoluteFile(), testJar.getAbsoluteFile());
|
||||
String[] expectedStrings = {
|
||||
"WARNING: Passing class file uncompressed due to unrecognized" +
|
||||
" attribute: Foo.class",
|
||||
"INFO: com.sun.java.util.jar.pack.Attribute$FormatException: " +
|
||||
"class attribute \"XourceFile\": is unknown attribute " +
|
||||
"in class Foo",
|
||||
"INFO: com.sun.java.util.jar.pack.ClassReader$ClassFormatException: " +
|
||||
"AnnotationDefault: attribute length cannot be zero, in Test.message()",
|
||||
"WARNING: Passing class file uncompressed due to unknown class format: Test.class"
|
||||
};
|
||||
List<String> notfoundList = new ArrayList<String>();
|
||||
notfoundList.addAll(Arrays.asList(expectedStrings));
|
||||
// make sure the expected messages are emitted
|
||||
for (String x : output) {
|
||||
findString(x, notfoundList, expectedStrings);
|
||||
}
|
||||
if (!notfoundList.isEmpty()) {
|
||||
System.out.println("Not found:");
|
||||
for (String x : notfoundList) {
|
||||
System.out.println(x);
|
||||
}
|
||||
throw new Exception("Test fails: " + notfoundList.size() +
|
||||
" expected strings not found");
|
||||
}
|
||||
testJar.delete();
|
||||
badAttrJar.delete();
|
||||
}
|
||||
|
||||
private static void findString(String outputStr, List<String> notfoundList,
|
||||
String[] expectedStrings) {
|
||||
for (String y : expectedStrings) {
|
||||
if (outputStr.contains(y)) {
|
||||
notfoundList.remove(y);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
jdk/test/tools/pack200/badattr.jar
Normal file
BIN
jdk/test/tools/pack200/badattr.jar
Normal file
Binary file not shown.
BIN
jdk/test/tools/pack200/dyn.jar
Normal file
BIN
jdk/test/tools/pack200/dyn.jar
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user