diff --git a/third_party/ijar/classfile.cc b/third_party/ijar/classfile.cc index d04f4e41b3110a..57a89d6a21dbb2 100644 --- a/third_party/ijar/classfile.cc +++ b/third_party/ijar/classfile.cc @@ -425,6 +425,7 @@ struct Attribute { virtual ~Attribute() {} virtual void Write(u1 *&p) = 0; virtual void ExtractClassNames() {} + virtual bool KeepForCompile() const { return false; } void WriteProlog(u1 *&p, u2 length) { put_u2be(p, attribute_name_->slot()); @@ -434,10 +435,6 @@ struct Attribute { Constant *attribute_name_; }; -struct KeepForCompileAttribute : Attribute { - void Write(u1 *&p) { WriteProlog(p, 0); } -}; - struct HasAttrs { std::vector attributes; @@ -1080,6 +1077,15 @@ struct AnnotationsAttribute : Attribute { } } + virtual bool KeepForCompile() const { + for (auto *annotation : annotations_) { + if (annotation->type_->Display() == "Lkotlin/Metadata;") { + return true; + } + } + return false; + } + void Write(u1 *&p) { WriteProlog(p, -1); u1 *payload_start = p - 4; @@ -1410,7 +1416,7 @@ struct ClassFile : HasAttrs { bool ReadConstantPool(const u1 *&p); - bool IsExplicitlyKept(); + bool KeepForCompile(); bool IsLocalOrAnonymous(); @@ -1530,10 +1536,6 @@ void HasAttrs::ReadAttrs(const u1 *&p) { } else if (attr_name == "PermittedSubclasses") { attributes.push_back( PermittedSubclassesAttribute::Read(p, attribute_name)); - } else if (attr_name == "com.google.devtools.ijar.KeepForCompile") { - auto attr = new KeepForCompileAttribute; - attr->attribute_name_ = attribute_name; - attributes.push_back(attr); } else { // Skip over unknown attributes with a warning. The JVM spec // says this is ok, so long as we handle the mandatory attributes. @@ -1677,23 +1679,17 @@ bool ClassFile::IsLocalOrAnonymous() { static bool HasKeepForCompile(const std::vector attributes) { for (const Attribute *attribute : attributes) { - if (attribute->attribute_name_->Display() == - "com.google.devtools.ijar.KeepForCompile") { + if (attribute->KeepForCompile()) { return true; } } return false; } -bool ClassFile::IsExplicitlyKept() { +bool ClassFile::KeepForCompile() { if (HasKeepForCompile(attributes)) { return true; } - for (const Member *method : methods) { - if (HasKeepForCompile(method->attributes)) { - return true; - } - } return false; } @@ -1744,12 +1740,6 @@ static ClassFile *ReadClass(const void *classdata, size_t length) { for (int ii = 0; ii < methods_count; ++ii) { Member *method = Member::Read(p); - if (HasKeepForCompile(method->attributes)) { - // Always keep methods marked as such - clazz->methods.push_back(method); - continue; - } - // drop class initializers if (method->name->Display() == "") continue; @@ -1950,10 +1940,8 @@ void ClassFile::WriteClass(u1 *&p) { bool StripClass(u1 *&classdata_out, const u1 *classdata_in, size_t in_length) { ClassFile *clazz = ReadClass(classdata_in, in_length); bool keep = true; - if (clazz == NULL || clazz->IsExplicitlyKept()) { + if (clazz == NULL || clazz->KeepForCompile()) { // Class is invalid or kept. Simply copy it to the output and call it a day. - // TODO: If kept, only emit methods marked with KeepForCompile attribute, - // as opposed to the entire type. put_n(classdata_out, classdata_in, in_length); } else if (clazz->IsLocalOrAnonymous()) { keep = false; diff --git a/third_party/ijar/test/GenKeepForCompile.java b/third_party/ijar/test/GenKeepForCompile.java index 2280955e0ccf84..ea5139fe4cedae 100644 --- a/third_party/ijar/test/GenKeepForCompile.java +++ b/third_party/ijar/test/GenKeepForCompile.java @@ -16,16 +16,14 @@ import java.util.jar.JarOutputStream; import java.util.zip.ZipEntry; import org.objectweb.asm.AnnotationVisitor; -import org.objectweb.asm.Attribute; -import org.objectweb.asm.ByteVector; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; /** - * GenKeepForCompile creates a jarfile containing a class definition that has the KeepForCOmpile - * attribute. + * GenKeepForCompile creates a jarfile containing a class definition that has the kotlin.Metadata + * annotation. */ public class GenKeepForCompile implements Opcodes { @@ -62,7 +60,15 @@ public static byte[] dump() throws Exception { AnnotationVisitor annotationVisitor1 = annotationVisitor0.visitArray("d1"); annotationVisitor1.visit( null, - "\u0000\u0014\n\u0000\n\u0002\u0010\u000e\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\u0010\u0008\u001a!\u0010\u0000\u001a\u00020\u0001*\u00020\u00022\u0012\u0010\u0003\u001a\u000e\u0012\u0004\u0012\u00020\u0005\u0012\u0004\u0012\u00020\u00010\u0004H\u0086\u0008"); + "\u0000\u0014\n" + + "\u0000\n" + + "\u0002\u0010\u000e\n" + + "\u0002\u0018\u0002\n" + + "\u0000\n" + + "\u0002\u0018\u0002\n" + + "\u0002\u0010\u0008\u001a!\u0010\u0000\u001a\u00020\u0001*\u00020\u00022\u0012" + + "\u0010\u0003\u001a\u000e\u0012\u0004\u0012\u00020\u0005\u0012\u0004\u0012\u00020" + + "\u00010\u0004H\u0086\u0008"); annotationVisitor1.visitEnd(); } { @@ -103,17 +109,6 @@ public static byte[] dump() throws Exception { methodVisitor.visitParameterAnnotation(1, "Lorg/jetbrains/annotations/NotNull;", false); annotationVisitor0.visitEnd(); } - // ATTRIBUTE com.google.devtools.ijar.KeepForCompile - // ASM-ifier doesn't emit attributes it does not know about :( - emitting by hand here. - methodVisitor.visitAttribute( - new Attribute("com.google.devtools.ijar.KeepForCompile") { - @Override - public ByteVector write( - ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) { - // nothing to write, just get the attribute's name in the file. - return new ByteVector(); - } - }); methodVisitor.visitCode(); Label label0 = new Label(); diff --git a/third_party/ijar/test/ijar_test.sh b/third_party/ijar/test/ijar_test.sh index f68fcf2d6eabd9..e916046bca5eee 100755 --- a/third_party/ijar/test/ijar_test.sh +++ b/third_party/ijar/test/ijar_test.sh @@ -576,11 +576,6 @@ function test_keep_for_compile() { grep -c "// Method kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull" || true) check_eq 2 $lines "Output jar should have kept method body" - attr=$($JAVAP -classpath $TEST_TMPDIR/keep.jar -v -p \ - functions.car.CarInlineUtilsKt | - strings | - grep -c "com.google.devtools.ijar.KeepForCompile" || true) - check_eq 2 $attr "Output jar should have kept KeepForCompile attribute." } function test_central_dir_largest_regular() {