8242039: Improve jlink VersionPropsPlugin

Reviewed-by: redestad
This commit is contained in:
Christoph Langer 2020-04-14 21:43:34 +02:00
parent e969c158d8
commit 3602186430
2 changed files with 58 additions and 13 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -88,6 +88,7 @@ class VersionProps {
"@@VENDOR_URL_BUG@@"; "@@VENDOR_URL_BUG@@";
// This field is read by HotSpot // This field is read by HotSpot
@SuppressWarnings("unused")
private static String VENDOR_URL_VM_BUG = private static String VENDOR_URL_VM_BUG =
"@@VENDOR_URL_VM_BUG@@"; "@@VENDOR_URL_VM_BUG@@";

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,18 +25,25 @@
package jdk.tools.jlink.internal.plugins; package jdk.tools.jlink.internal.plugins;
import java.io.*; import java.util.Map;
import java.nio.charset.*;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;
import jdk.tools.jlink.plugin.*;
import jdk.internal.org.objectweb.asm.*;
import static java.lang.System.out; import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.ResourcePoolEntry;
/** /**
* Base plugin to update a static field in java.lang.VersionProps * Base plugin to update a static field in java.lang.VersionProps
*
* Fields to be updated must not be final such that values are not constant
* replaced at compile time and initialization code is generated.
* We assume that the initialization code only has ldcs, method calls and
* field instructions.
*/ */
abstract class VersionPropsPlugin implements Plugin { abstract class VersionPropsPlugin implements Plugin {
@ -113,6 +120,7 @@ abstract class VersionPropsPlugin implements Plugin {
cr.accept(new ClassVisitor(Opcodes.ASM7, cw) { cr.accept(new ClassVisitor(Opcodes.ASM7, cw) {
@Override
public MethodVisitor visitMethod(int access, public MethodVisitor visitMethod(int access,
String name, String name,
String desc, String desc,
@ -127,7 +135,33 @@ abstract class VersionPropsPlugin implements Plugin {
sig, sig,
xs)) xs))
{ {
private Object pendingLDC = null;
private void flushPendingLDC() {
if (pendingLDC != null) {
super.visitLdcInsn(pendingLDC);
pendingLDC = null;
}
}
@Override
public void visitLdcInsn(Object value) {
flushPendingLDC();
pendingLDC = value;
}
@Override
public void visitMethodInsn(int opcode,
String owner,
String name,
String descriptor,
boolean isInterface) {
flushPendingLDC();
super.visitMethodInsn(opcode, owner, name,
descriptor, isInterface);
}
@Override
public void visitFieldInsn(int opcode, public void visitFieldInsn(int opcode,
String owner, String owner,
String name, String name,
@ -136,11 +170,21 @@ abstract class VersionPropsPlugin implements Plugin {
if (opcode == Opcodes.PUTSTATIC if (opcode == Opcodes.PUTSTATIC
&& name.equals(field)) && name.equals(field))
{ {
// Discard the original value // assert that there is a pending ldc
super.visitInsn(Opcodes.POP); // for the old value
// Load the value that we want if (pendingLDC == null) {
throw new AssertionError("No load " +
"instruction found for field " + field +
" in static initializer of " +
VERSION_PROPS_CLASS);
}
// forget about it
pendingLDC = null;
// and add an ldc for the new value
super.visitLdcInsn(value); super.visitLdcInsn(value);
redefined = true; redefined = true;
} else {
flushPendingLDC();
} }
super.visitFieldInsn(opcode, owner, super.visitFieldInsn(opcode, owner,
name, desc); name, desc);