--- a/hotspot/src/share/vm/oops/cpCache.cpp Wed Aug 30 19:18:22 2017 -0400
+++ b/hotspot/src/share/vm/oops/cpCache.cpp Mon Aug 28 15:34:04 2017 -0700
@@ -23,6 +23,8 @@
*/
#include "precompiled.hpp"
+#include "interpreter/bytecodeStream.hpp"
+#include "interpreter/bytecodes.hpp"
#include "interpreter/interpreter.hpp"
#include "interpreter/rewriter.hpp"
#include "logging/log.hpp"
@@ -49,6 +51,24 @@
assert(constant_pool_index() == index, "");
}
+void ConstantPoolCacheEntry::verify_just_initialized(bool f2_used) {
+ assert((_indices & (~cp_index_mask)) == 0, "sanity");
+ assert(_f1 == NULL, "sanity");
+ assert(_flags == 0, "sanity");
+ if (!f2_used) {
+ assert(_f2 == 0, "sanity");
+ }
+}
+
+void ConstantPoolCacheEntry::reinitialize(bool f2_used) {
+ _indices &= cp_index_mask;
+ _f1 = NULL;
+ _flags = 0;
+ if (!f2_used) {
+ _f2 = 0;
+ }
+}
+
int ConstantPoolCacheEntry::make_flags(TosState state,
int option_bits,
int field_index_or_method_params) {
@@ -609,6 +629,66 @@
}
}
+void ConstantPoolCache::verify_just_initialized() {
+ DEBUG_ONLY(walk_entries_for_initialization(/*check_only = */ true));
+}
+
+void ConstantPoolCache::remove_unshareable_info() {
+ walk_entries_for_initialization(/*check_only = */ false);
+}
+
+void ConstantPoolCache::walk_entries_for_initialization(bool check_only) {
+ assert(DumpSharedSpaces, "sanity");
+ // When dumping the archive, we want to clean up the ConstantPoolCache
+ // to remove any effect of linking due to the execution of Java code --
+ // each ConstantPoolCacheEntry will have the same contents as if
+ // ConstantPoolCache::initialize has just returned:
+ //
+ // - We keep the ConstantPoolCache::constant_pool_index() bits for all entries.
+ // - We keep the "f2" field for entries used by invokedynamic and invokehandle
+ // - All other bits in the entries are cleared to zero.
+ ResourceMark rm;
+
+ InstanceKlass* ik = constant_pool()->pool_holder();
+ bool* f2_used = NEW_RESOURCE_ARRAY(bool, length());
+ memset(f2_used, 0, sizeof(bool) * length());
+
+ // Find all the slots that we need to preserve f2
+ for (int i = 0; i < ik->methods()->length(); i++) {
+ Method* m = ik->methods()->at(i);
+ RawBytecodeStream bcs(m);
+ while (!bcs.is_last_bytecode()) {
+ Bytecodes::Code opcode = bcs.raw_next();
+ switch (opcode) {
+ case Bytecodes::_invokedynamic: {
+ int index = Bytes::get_native_u4(bcs.bcp() + 1);
+ int cp_cache_index = constant_pool()->invokedynamic_cp_cache_index(index);
+ f2_used[cp_cache_index] = 1;
+ }
+ break;
+ case Bytecodes::_invokehandle: {
+ int cp_cache_index = Bytes::get_native_u2(bcs.bcp() + 1);
+ f2_used[cp_cache_index] = 1;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (check_only) {
+ DEBUG_ONLY(
+ for (int i=0; i<length(); i++) {
+ entry_at(i)->verify_just_initialized(f2_used[i]);
+ })
+ } else {
+ for (int i=0; i<length(); i++) {
+ entry_at(i)->reinitialize(f2_used[i]);
+ }
+ }
+}
+
void ConstantPoolCache::deallocate_contents(ClassLoaderData* data) {
assert(!is_shared(), "shared caches are not deallocated");
data->remove_handle(_resolved_references);