Mercurial > hg > graal-jvmci-8
changeset 22924:12eb26c15642
Merge
author | tschatzl |
---|---|
date | Tue, 31 Mar 2015 16:12:22 +0000 |
parents | c04f46b4abe4 (current diff) 423484d91bfb (diff) |
children | 6d13c17668d1 |
files | |
diffstat | 11 files changed, 408 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Tue Mar 31 11:36:37 2015 +0200 +++ b/.hgtags Tue Mar 31 16:12:22 2015 +0000 @@ -605,3 +605,5 @@ d51ef6da82b486e7b2b3c08eef9ca0a186935ded hs25.60-b07 353e580ce6878d80c7b7cd27f8ad24609b12c58b jdk8u60-b07 a72a4192a36d6d84766d6135fe6515346c742007 hs25.60-b08 +bf68e15dc8fe73eeb1eb3c656df51fdb1f707a97 jdk8u60-b08 +d937e6a0674841d670232ecf1611f52e1ae998e7 hs25.60-b09
--- a/make/hotspot_version Tue Mar 31 11:36:37 2015 +0200 +++ b/make/hotspot_version Tue Mar 31 16:12:22 2015 +0000 @@ -35,7 +35,7 @@ HS_MAJOR_VER=25 HS_MINOR_VER=60 -HS_BUILD_NUMBER=09 +HS_BUILD_NUMBER=10 JDK_MAJOR_VER=1 JDK_MINOR_VER=8
--- a/src/share/vm/classfile/verifier.cpp Tue Mar 31 11:36:37 2015 +0200 +++ b/src/share/vm/classfile/verifier.cpp Tue Mar 31 16:12:22 2015 +0000 @@ -655,6 +655,7 @@ bool this_uninit = false; // Set to true when invokespecial <init> initialized 'this' + bool verified_exc_handlers = false; // Merge with the next instruction { @@ -686,6 +687,18 @@ } } + // Look for possible jump target in exception handlers and see if it + // matches current_frame. Do this check here for astore*, dstore*, + // fstore*, istore*, and lstore* opcodes because they can change the type + // state by adding a local. JVM Spec says that the incoming type state + // should be used for this check. So, do the check here before a possible + // local is added to the type state. + if (Bytecodes::is_store_into_local(opcode) && bci >= ex_min && bci < ex_max) { + verify_exception_handler_targets( + bci, this_uninit, ¤t_frame, &stackmap_table, CHECK_VERIFY(this)); + verified_exc_handlers = true; + } + switch (opcode) { case Bytecodes::_nop : no_control_flow = false; break; @@ -1662,9 +1675,13 @@ } // end switch } // end Merge with the next instruction - // Look for possible jump target in exception handlers and see if it - // matches current_frame - if (bci >= ex_min && bci < ex_max) { + // Look for possible jump target in exception handlers and see if it matches + // current_frame. Don't do this check if it has already been done (for + // ([a,d,f,i,l]store* opcodes). This check cannot be done earlier because + // opcodes, such as invokespecial, may set the this_uninit flag. + assert(!(verified_exc_handlers && this_uninit), + "Exception handler targets got verified before this_uninit got set"); + if (!verified_exc_handlers && bci >= ex_min && bci < ex_max) { verify_exception_handler_targets( bci, this_uninit, ¤t_frame, &stackmap_table, CHECK_VERIFY(this)); }
--- a/src/share/vm/interpreter/bytecodes.hpp Tue Mar 31 11:36:37 2015 +0200 +++ b/src/share/vm/interpreter/bytecodes.hpp Tue Mar 31 16:12:22 2015 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2015, 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 @@ -420,6 +420,7 @@ static bool is_astore (Code code) { return (code == _astore || code == _astore_0 || code == _astore_1 || code == _astore_2 || code == _astore_3); } + static bool is_store_into_local(Code code){ return (_istore <= code && code <= _astore_3); } static bool is_const (Code code) { return (_aconst_null <= code && code <= _ldc2_w); } static bool is_zero_const (Code code) { return (code == _aconst_null || code == _iconst_0 || code == _fconst_0 || code == _dconst_0); }
--- a/src/share/vm/interpreter/oopMapCache.cpp Tue Mar 31 11:36:37 2015 +0200 +++ b/src/share/vm/interpreter/oopMapCache.cpp Tue Mar 31 16:12:22 2015 +0000 @@ -244,10 +244,8 @@ method()->print_value(); tty->print(" @ %d = [%d] { ", bci(), n); for (int i = 0; i < n; i++) { -#ifdef ENABLE_ZAP_DEAD_LOCALS if (is_dead(i)) tty->print("%d+ ", i); else -#endif if (is_oop(i)) tty->print("%d ", i); } tty->print_cr("}"); @@ -402,13 +400,11 @@ value |= (mask << oop_bit_number ); } - #ifdef ENABLE_ZAP_DEAD_LOCALS // set dead bit if (!cell->is_live()) { value |= (mask << dead_bit_number); assert(!cell->is_reference(), "dead value marked as oop"); } - #endif } // make sure last word is stored
--- a/src/share/vm/interpreter/oopMapCache.hpp Tue Mar 31 11:36:37 2015 +0200 +++ b/src/share/vm/interpreter/oopMapCache.hpp Tue Mar 31 16:12:22 2015 +0000 @@ -66,19 +66,15 @@ public: enum { - N = 2, // the number of words reserved + N = 4, // the number of words reserved // for inlined mask storage small_mask_limit = N * BitsPerWord, // the maximum number of bits // available for small masks, // small_mask_limit can be set to 0 // for testing bit_mask allocation -#ifdef ENABLE_ZAP_DEAD_LOCALS bits_per_entry = 2, dead_bit_number = 1, -#else - bits_per_entry = 1, -#endif oop_bit_number = 0 }; @@ -119,10 +115,6 @@ void set_expression_stack_size(int sz) { _expression_stack_size = sz; } -#ifdef ENABLE_ZAP_DEAD_LOCALS - bool is_dead(int offset) const { return (entry_at(offset) & (1 << dead_bit_number)) != 0; } -#endif - // Lookup bool match(methodHandle method, int bci) const { return _method == method() && _bci == bci; } bool is_empty() const; @@ -144,6 +136,7 @@ void print() const; int number_of_entries() const { return mask_size() / bits_per_entry; } + bool is_dead(int offset) const { return (entry_at(offset) & (1 << dead_bit_number)) != 0; } bool is_oop (int offset) const { return (entry_at(offset) & (1 << oop_bit_number )) != 0; } int expression_stack_size() const { return _expression_stack_size; }
--- a/src/share/vm/prims/jvmtiImpl.cpp Tue Mar 31 11:36:37 2015 +0200 +++ b/src/share/vm/prims/jvmtiImpl.cpp Tue Mar 31 16:12:22 2015 +0000 @@ -25,6 +25,7 @@ #include "precompiled.hpp" #include "classfile/systemDictionary.hpp" #include "interpreter/interpreter.hpp" +#include "interpreter/oopMapCache.hpp" #include "jvmtifiles/jvmtiEnv.hpp" #include "memory/resourceArea.hpp" #include "oops/instanceKlass.hpp" @@ -744,6 +745,13 @@ } void VM_GetOrSetLocal::doit() { + InterpreterOopMap oop_mask; + _jvf->method()->mask_for(_jvf->bci(), &oop_mask); + if (oop_mask.is_dead(_index)) { + // The local can be invalid and uninitialized in the scope of current bci + _result = JVMTI_ERROR_INVALID_SLOT; + return; + } if (_set) { // Force deoptimization of frame if compiled because it's // possible the compiler emitted some locals as constant values,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/stackMapCheck/BadMap.jasm Tue Mar 31 16:12:22 2015 +0000 @@ -0,0 +1,152 @@ + /* + * Copyright (c) 2015, 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. + * + */ + +/* + * This class should throw VerifyError because the StackMap for bytecode index + * 45 (astore_2, line 123) is incorrect. The stack maps for bytecode indexes 45 + * and 49 (astore, line 133) do not match because 45 does not supply enough + * locals to satisfy 49. + * + * The astore_2 bytecode at bytecode index 45 changes the type state, + * preventing the stackmap mismatch. But, if the incoming type state is used, + * as required by JVM Spec 8, then the verifier will detected the stackmap + * mismatch, and throw VerifyError. + */ + +super public class BadMap + version 51:0 +{ + + +public Method "<init>":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."<init>":"()V"; + return; +} + +public static Method main:"([Ljava/lang/String;)V" + throws java/lang/Throwable + stack 0 locals 1 +{ + return; +} + +public static Method foo:"()V" + stack 3 locals 5 +{ + iconst_0; + ifne L5; + nop; + try t7; + L5: stack_frame_type full; + aconst_null; + dup; + astore_0; + astore_1; + try t0; + aconst_null; + astore_0; + endtry t0; + goto L19; + catch t0 java/io/IOException; + stack_frame_type full; + locals_map class java/lang/Object, null; + stack_map class java/io/IOException; + astore_2; + aconst_null; + dup; + astore_1; + astore_0; + try t1; + L19: stack_frame_type full; + locals_map class java/lang/Object, class java/lang/Object; + aconst_null; + astore_2; + endtry t1; + aload_1; + ifnonnull L37; + nop; + goto L37; + catch t1 #0; + catch t2 #0; + try t2; + stack_frame_type full; + locals_map class java/lang/Object, class java/lang/Object; + stack_map class java/lang/Throwable; + astore_3; + endtry t2; + aload_1; + ifnonnull L35; + nop; + L35: stack_frame_type full; + locals_map class java/lang/Object, class java/lang/Object, bogus, class java/lang/Throwable; + aload_3; + athrow; + try t3, t4; + L37: stack_frame_type full; + locals_map class java/lang/Object, class java/lang/Object, class java/lang/Object; + aload_1; + ifnonnull L42; + nop; + endtry t3, t4; + L42: stack_frame_type full; + locals_map class java/lang/Object, class java/lang/Object, class java/lang/Object; + goto L54; + catch t3 java/lang/Exception; + try t5; + stack_frame_type full; + locals_map class java/lang/Object, class java/lang/Object; + stack_map class java/lang/Exception; + astore_2; // astore_2, at bci 45, that changes the type state. + endtry t5; + goto L54; + catch t4 #0; + catch t5 #0; + catch t6 #0; + try t6; + stack_frame_type full; + locals_map class java/lang/Object, class java/lang/Object, class java/lang/Object; + stack_map class java/lang/Throwable; + astore 4; + endtry t6; + aload 4; + athrow; + L54: stack_frame_type full; + locals_map class java/lang/Object, class java/lang/Object, class java/lang/Object; + goto L57; + L57: stack_frame_type full; + locals_map class java/lang/Object, class java/lang/Object, class java/lang/Object; + nop; + endtry t7; + return; + catch t7 #0; + stack_frame_type full; + stack_map class java/lang/Throwable; + nop; + athrow; +} + +} // end Class BadMap
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/stackMapCheck/BadMapDstore.jasm Tue Mar 31 16:12:22 2015 +0000 @@ -0,0 +1,79 @@ + /* + * Copyright (c) 2015, 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. + * + */ + +/* + * This class should throw VerifyError because the StackMap for bytecode index + * 9 (dstore_2, line 60) is incorrect. The stack maps for bytecode indexes 9 + * and 18 (astore_2, line 70) do not match because 9 does not supply enough + * locals to satisfy 18. + * + * The dstore_2 bytecode at bytecode index 9 changes the type state, + * preventing the stackmap mismatch. But, if the incoming type state is used, + * as required by JVM Spec 8, then the verifier will detected the stackmap + * mismatch, and throw VerifyError. + */ + +super public class BadMapDstore + version 51:0 +{ + +Field blah:I; + +public Method "<init>":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."<init>":"()V"; + return; +} + +public static Method main:"([Ljava/lang/String;)V" + stack 4 locals 4 +{ + new class BadMapDstore; + dup; + invokespecial Method "<init>":"()V"; + astore_1; + dconst_1; + try t0; + dstore_2; + aload_1; + iconst_5; + putfield Field blah:"I"; + endtry t0; + goto L22; + catch t0 java/lang/Throwable; + stack_frame_type full; + locals_map class "[Ljava/lang/String;", class BadMapDstore, double; + stack_map class java/lang/Throwable; + astore_2; + aload_1; + dconst_0; + dstore_2; + pop; + L22: stack_frame_type same; + return; +} + +} // end Class BadMapDstore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/stackMapCheck/BadMapIstore.jasm Tue Mar 31 16:12:22 2015 +0000 @@ -0,0 +1,79 @@ + /* + * Copyright (c) 2015, 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. + * + */ + +/* + * This class should throw VerifyError because the StackMap for bytecode index + * 9 (istore_2, line 60) is incorrect. The stack maps for bytecode indexes 9 + * and 18 (astore_2, line 70) do not match because 9 does not supply enough + * locals to satisfy 18. + * + * The istore_2 bytecode at bytecode index 9 changes the type state, + * preventing the stackmap mismatch. But, if the incoming type state is used, + * as required by JVM Spec 8, then the verifier will detected the stackmap + * mismatch, and throw VerifyError. + */ + +super public class BadMapIstore + version 51:0 +{ + +Field blah:I; + +public Method "<init>":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."<init>":"()V"; + return; +} + +public static Method main:"([Ljava/lang/String;)V" + stack 2 locals 3 +{ + new class BadMapIstore; + dup; + invokespecial Method "<init>":"()V"; + astore_1; + iconst_2; + try t0; + istore_2; + aload_1; + iconst_5; + putfield Field blah:"I"; + endtry t0; + goto L22; + catch t0 java/lang/Throwable; + stack_frame_type full; + locals_map class "[Ljava/lang/String;", class BadMapIstore, int; + stack_map class java/lang/Throwable; + astore_2; + aload_1; + iconst_4; + istore_2; + pop; + L22: stack_frame_type same; + return; +} + +} // end Class BadMapIstore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/stackMapCheck/StackMapCheck.java Tue Mar 31 16:12:22 2015 +0000 @@ -0,0 +1,63 @@ + /* + * Copyright (c) 2015, 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. + * + */ + +/* + * @test + * @bug 7127066 + * @summary Class verifier accepts an invalid class file + * @compile BadMap.jasm + * @compile BadMapDstore.jasm + * @compile BadMapIstore.jasm + * @run main/othervm -Xverify:all StackMapCheck + */ + +public class StackMapCheck { + public static void main(String args[]) throws Throwable { + + System.out.println("Regression test for bug 7127066"); + try { + Class newClass = Class.forName("BadMap"); + throw new RuntimeException( + "StackMapCheck failed, BadMap did not throw VerifyError"); + } catch (java.lang.VerifyError e) { + System.out.println("BadMap passed, VerifyError was thrown"); + } + + try { + Class newClass = Class.forName("BadMapDstore"); + throw new RuntimeException( + "StackMapCheck failed, BadMapDstore did not throw VerifyError"); + } catch (java.lang.VerifyError e) { + System.out.println("BadMapDstore passed, VerifyError was thrown"); + } + + try { + Class newClass = Class.forName("BadMapIstore"); + throw new RuntimeException( + "StackMapCheck failed, BadMapIstore did not throw VerifyError"); + } catch (java.lang.VerifyError e) { + System.out.println("BadMapIstore passed, VerifyError was thrown"); + } + } +}