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
--- a/hotspot/src/share/vm/interpreter/rewriter.cpp Fri Feb 07 11:47:24 2014 -0800
+++ b/hotspot/src/share/vm/interpreter/rewriter.cpp Fri Feb 07 18:30:27 2014 -0500
@@ -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 @@
// 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 @@
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<Method*>* 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 @@
// May have to fix invokedynamic bytecodes if invokestatic/InterfaceMethodref
// entries had to be added.
patch_invokedynamic_bytecodes();
+}
+
+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<Method*>* 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 @@
// so methods with jsrs in custom class lists in aren't attempted to be
// rewritten in the RO section of the shared archive.
// Relocated bytecodes don't have to be restored, only the cp cache entries
+ int len = _methods->length();
for (int i = len-1; i >= 0; i--) {
methodHandle m(THREAD, _methods->at(i));
--- a/hotspot/src/share/vm/interpreter/rewriter.hpp Fri Feb 07 11:47:24 2014 -0800
+++ b/hotspot/src/share/vm/interpreter/rewriter.hpp Fri Feb 07 18:30:27 2014 -0500
@@ -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 @@
void patch_invokedynamic_bytecodes();
+ // Do all the work.
+ void rewrite_bytecodes(TRAPS);
+
// Revert bytecodes in case of an exception.
void restore_bytecodes();
--- a/hotspot/src/share/vm/oops/constantPool.cpp Fri Feb 07 11:47:24 2014 -0800
+++ b/hotspot/src/share/vm/oops/constantPool.cpp Fri Feb 07 18:30:27 2014 -0500
@@ -82,6 +82,9 @@
void ConstantPool::deallocate_contents(ClassLoaderData* loader_data) {
MetadataFactory::free_metadata(loader_data, cache());
set_cache(NULL);
+ MetadataFactory::free_array<u2>(loader_data, reference_map());
+ set_reference_map(NULL);
+
MetadataFactory::free_array<jushort>(loader_data, operands());
set_operands(NULL);
--- a/hotspot/src/share/vm/runtime/globals.hpp Fri Feb 07 11:47:24 2014 -0800
+++ b/hotspot/src/share/vm/runtime/globals.hpp Fri Feb 07 18:30:27 2014 -0500
@@ -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
@@ -1260,6 +1260,9 @@
develop(bool, TraceJNICalls, false, \
"Trace JNI calls") \
\
+ develop(bool, StressRewriter, false, \
+ "Stress linktime bytecode rewriting") \
+ \
notproduct(bool, TraceJVMCalls, false, \
"Trace JVM calls") \
\
--- a/hotspot/src/share/vm/utilities/array.hpp Fri Feb 07 11:47:24 2014 -0800
+++ b/hotspot/src/share/vm/utilities/array.hpp Fri Feb 07 18:30:27 2014 -0500
@@ -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 @@
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();)
--- a/hotspot/test/runtime/lambda-features/InvokespecialInterface.java Fri Feb 07 11:47:24 2014 -0800
+++ b/hotspot/test/runtime/lambda-features/InvokespecialInterface.java Fri Feb 07 18:30:27 2014 -0500
@@ -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.*;