From d10216774bd892c8025f1e60dbe82124f15379e3 Mon Sep 17 00:00:00 2001 From: coleenp Date: Fri, 7 Feb 2014 18:30:27 -0500 Subject: [PATCH] 8033528: assert(0 <= i && i < length()) failed: index out of bounds Summary: Restoring bytecodes for invokedynamic had wrong index calculation added testing stress option. Reviewed-by: twisti, hseigel --- src/share/vm/interpreter/rewriter.cpp | 43 ++++++++++++------- src/share/vm/interpreter/rewriter.hpp | 5 ++- src/share/vm/oops/constantPool.cpp | 3 ++ src/share/vm/runtime/globals.hpp | 5 ++- src/share/vm/utilities/array.hpp | 4 +- .../InvokespecialInterface.java | 3 +- 6 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/share/vm/interpreter/rewriter.cpp b/src/share/vm/interpreter/rewriter.cpp index 208f8617d..2474ae758 100644 --- a/src/share/vm/interpreter/rewriter.cpp +++ b/src/share/vm/interpreter/rewriter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, 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 @@ -250,8 +250,8 @@ void Rewriter::rewrite_invokedynamic(address bcp, int offset, bool reverse) { // We will reverse the bytecode rewriting _after_ adjusting them. // Adjust the cache index by offset to the invokedynamic entries in the // cpCache plus the delta if the invokedynamic bytecodes were adjusted. - cache_index = cp_cache_delta() + _first_iteration_cp_cache_limit; - int cp_index = invokedynamic_cp_cache_entry_pool_index(cache_index); + int adjustment = cp_cache_delta() + _first_iteration_cp_cache_limit; + int cp_index = invokedynamic_cp_cache_entry_pool_index(cache_index - adjustment); assert(_pool->tag_at(cp_index).is_invoke_dynamic(), "wrong index"); // zero out 4 bytes Bytes::put_Java_u4(p, 0); @@ -453,18 +453,7 @@ methodHandle Rewriter::rewrite_jsrs(methodHandle method, TRAPS) { return method; } -void Rewriter::rewrite(instanceKlassHandle klass, TRAPS) { - ResourceMark rm(THREAD); - Rewriter rw(klass, klass->constants(), klass->methods(), CHECK); - // (That's all, folks.) -} - - -Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array* methods, TRAPS) - : _klass(klass), - _pool(cpool), - _methods(methods) -{ +void Rewriter::rewrite_bytecodes(TRAPS) { assert(_pool->cache() == NULL, "constant pool cache must not be set yet"); // determine index maps for Method* rewriting @@ -508,6 +497,29 @@ Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Arrayconstants(), klass->methods(), CHECK); + // (That's all, folks.) +} + + +Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array* methods, TRAPS) + : _klass(klass), + _pool(cpool), + _methods(methods) +{ + + // Rewrite bytecodes - exception here exits. + rewrite_bytecodes(CHECK); + + // Stress restoring bytecodes + if (StressRewriter) { + restore_bytecodes(); + rewrite_bytecodes(CHECK); + } // allocate constant pool cache, now that we've seen all the bytecodes make_constant_pool_cache(THREAD); @@ -523,6 +535,7 @@ Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Arraylength(); for (int i = len-1; i >= 0; i--) { methodHandle m(THREAD, _methods->at(i)); diff --git a/src/share/vm/interpreter/rewriter.hpp b/src/share/vm/interpreter/rewriter.hpp index 2c7990fa7..aa4b7cd52 100644 --- a/src/share/vm/interpreter/rewriter.hpp +++ b/src/share/vm/interpreter/rewriter.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2014, 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 @@ -199,6 +199,9 @@ class Rewriter: public StackObj { void patch_invokedynamic_bytecodes(); + // Do all the work. + void rewrite_bytecodes(TRAPS); + // Revert bytecodes in case of an exception. void restore_bytecodes(); diff --git a/src/share/vm/oops/constantPool.cpp b/src/share/vm/oops/constantPool.cpp index 16b53a699..3f37810d2 100644 --- a/src/share/vm/oops/constantPool.cpp +++ b/src/share/vm/oops/constantPool.cpp @@ -82,6 +82,9 @@ ConstantPool::ConstantPool(Array* tags) { void ConstantPool::deallocate_contents(ClassLoaderData* loader_data) { MetadataFactory::free_metadata(loader_data, cache()); set_cache(NULL); + MetadataFactory::free_array(loader_data, reference_map()); + set_reference_map(NULL); + MetadataFactory::free_array(loader_data, operands()); set_operands(NULL); diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp index e7f634096..9d9ecacc4 100644 --- a/src/share/vm/runtime/globals.hpp +++ b/src/share/vm/runtime/globals.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, 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 @@ -1258,6 +1258,9 @@ class CommandLineFlags { develop(bool, TraceJNICalls, false, \ "Trace JNI calls") \ \ + develop(bool, StressRewriter, false, \ + "Stress linktime bytecode rewriting") \ + \ notproduct(bool, TraceJVMCalls, false, \ "Trace JVM calls") \ \ diff --git a/src/share/vm/utilities/array.hpp b/src/share/vm/utilities/array.hpp index 9f8e45f32..0fbcd94d2 100644 --- a/src/share/vm/utilities/array.hpp +++ b/src/share/vm/utilities/array.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2014, 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 @@ -58,7 +58,7 @@ class ResourceArray: public ResourceObj { void initialize(size_t esize, int length) { assert(length >= 0, "illegal length"); - assert(_data == NULL, "must be new object"); + assert(StressRewriter || _data == NULL, "must be new object"); _length = length; _data = resource_allocate_bytes(esize * length); DEBUG_ONLY(init_nesting();) diff --git a/test/runtime/lambda-features/InvokespecialInterface.java b/test/runtime/lambda-features/InvokespecialInterface.java index 25e7904c2..80c26186d 100644 --- a/test/runtime/lambda-features/InvokespecialInterface.java +++ b/test/runtime/lambda-features/InvokespecialInterface.java @@ -26,8 +26,9 @@ * @test * @bug 8032024 * @bug 8025937 + * @bug 8033528 * @summary [JDK 8] Test invokespecial and invokeinterface with the same JVM_CONSTANT_InterfaceMethodref - * @run main InvokespecialInterface + * @run main/othervm -XX:+StressRewriter InvokespecialInterface */ import java.util.function.*; import java.util.*; -- GitLab