From david.lloyd at redhat.com Wed Oct 1 12:31:18 2025 From: david.lloyd at redhat.com (David Lloyd) Date: Wed, 1 Oct 2025 07:31:18 -0500 Subject: DROP_DEBUG and the constant pool In-Reply-To: References: Message-ID: OK, shall I prepare a bug report and patch? Thanks. On Tue, Sep 30, 2025 at 2:55?PM Chen Liang wrote: > Hi David, this seems a legitimate bug. > > I think we can bypass this by using the TemporaryConstantPool.INSTANCE to > construct the UTF-8 entries. > > Regards, Chen > ------------------------------ > *From:* classfile-api-dev on behalf > of David Lloyd > *Sent:* Tuesday, September 30, 2025 11:07 AM > *To:* classfile-api-dev at openjdk.org > *Cc:* Ladislav Thon > *Subject:* DROP_DEBUG and the constant pool > > We've observed that when using `DROP_DEBUG` in conjunction with > `CodeBuilder#localVariable` and/or `localVariableType`, some (otherwise > useless) constant pool entries are still being created (which contain, I > believe, both the variable name and descriptor). This was observed using a > backport of the JDK classfile API based on JDK 25. > > Would this be expected behavior? Is there a separate step needed to clean > the constant pool for cases like this? > > It looks to me to be the consequence of how the default methods for local > variable creation are implemented, e.g.: > > default CodeBuilder localVariable(int slot, String name, ClassDesc > descriptor, Label startScope, Label endScope) { > return localVariable(slot, > constantPool().utf8Entry(name), > constantPool().utf8Entry(descriptor), > startScope, endScope); > } > > The constant pool is accessed even when `DROP_DEBUG` is enabled, because > that flag is used later on in the process, and it seems that these entries > are never dropped, even if they are unused. > > -- > - DML ? he/him > -- - DML ? he/him -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Wed Oct 1 12:52:40 2025 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 1 Oct 2025 08:52:40 -0400 Subject: DROP_DEBUG and the constant pool In-Reply-To: References: Message-ID: <7105837a-dc37-41c6-851c-d20c7cc4c613@oracle.com> After thinking about it for a few more minutes, I'm less sure of this approach (and not sure I'd even classify it as a bug.)? While locally this change is probably harmless, there are dozens of uses of the idiom `constantPool().xxxEntry()` in this class -- why would we switch just some of them over to using the temp pool?? And switching all of them over falls into a more significant change in implementation approach, for which the bar is surely higher. In any case, I think we don't need to change anything; the code you want is already in the library.? Just do ? ? builder.with(LocalVariable.of(slot, name, desc, start, end)) since that's exactly what LocalVariable::of does: static LocalVariable of(int slot,String name,ClassDesc descriptor,Label startScope,Label endScope) { return of(slot, TemporaryConstantPool.INSTANCE.utf8Entry(name), TemporaryConstantPool.INSTANCE.utf8Entry(descriptor.descriptorString()), startScope,endScope); } } On 10/1/2025 8:31 AM, David Lloyd wrote: > OK, shall I prepare a bug report and patch? Thanks. > > On Tue, Sep 30, 2025 at 2:55?PM Chen Liang > wrote: > > Hi David, this seems a legitimate bug. > > I think we can bypass this by using the > TemporaryConstantPool.INSTANCE to construct the UTF-8 entries. > > Regards, Chen > ------------------------------------------------------------------------ > *From:* classfile-api-dev on > behalf of David Lloyd > *Sent:* Tuesday, September 30, 2025 11:07 AM > *To:* classfile-api-dev at openjdk.org > *Cc:* Ladislav Thon > *Subject:* DROP_DEBUG and the constant pool > We've observed that when using `DROP_DEBUG` in conjunction with > `CodeBuilder#localVariable` and/or `localVariableType`, some > (otherwise useless) constant pool entries are still being created > (which contain, I believe, both the variable name and descriptor). > This was observed using a backport of the JDK classfile API based > on JDK 25. > > Would this be expected behavior? Is there a separate step needed > to clean the constant pool for cases like this? > > It looks to me to be the consequence of how the default methods > for local variable creation are implemented, e.g.: > > ? default CodeBuilder localVariable(int slot, String name, > ClassDesc descriptor, Label startScope, Label endScope) { > ? ? ? ? return localVariable(slot, > ?constantPool().utf8Entry(name), > ?constantPool().utf8Entry(descriptor), > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?startScope, endScope); > ? ? } > > The constant pool is accessed even when `DROP_DEBUG` is enabled, > because that flag is used later on in the process, and it seems > that these entries are never dropped, even if they are unused. > > -- > - DML ? he/him > > > > -- > - DML ? he/him -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.lloyd at redhat.com Wed Oct 1 13:12:37 2025 From: david.lloyd at redhat.com (David Lloyd) Date: Wed, 1 Oct 2025 08:12:37 -0500 Subject: DROP_DEBUG and the constant pool In-Reply-To: <7105837a-dc37-41c6-851c-d20c7cc4c613@oracle.com> References: <7105837a-dc37-41c6-851c-d20c7cc4c613@oracle.com> Message-ID: Then perhaps the cleaner fix is instead to have the default methods delegate to `LocalVariable.of(int,String,ClassDesc,Label,Label)` directly? On Wed, Oct 1, 2025 at 7:52?AM Brian Goetz wrote: > After thinking about it for a few more minutes, I'm less sure of this > approach (and not sure I'd even classify it as a bug.) While locally this > change is probably harmless, there are dozens of uses of the idiom > `constantPool().xxxEntry()` in this class -- why would we switch just some > of them over to using the temp pool? And switching all of them over falls > into a more significant change in implementation approach, for which the > bar is surely higher. > > In any case, I think we don't need to change anything; the code you want > is already in the library. Just do > > builder.with(LocalVariable.of(slot, name, desc, start, end)) > > since that's exactly what LocalVariable::of does: > > static LocalVariable of(int slot, String name, ClassDesc descriptor, Label startScope, Label endScope) { > return of(slot, > TemporaryConstantPool.INSTANCE.utf8Entry(name), > TemporaryConstantPool.INSTANCE.utf8Entry(descriptor.descriptorString()), > startScope, endScope); > } > } > > > > > > > > > > > On 10/1/2025 8:31 AM, David Lloyd wrote: > > OK, shall I prepare a bug report and patch? Thanks. > > On Tue, Sep 30, 2025 at 2:55?PM Chen Liang > wrote: > >> Hi David, this seems a legitimate bug. >> >> I think we can bypass this by using the TemporaryConstantPool.INSTANCE to >> construct the UTF-8 entries. >> >> Regards, Chen >> ------------------------------ >> *From:* classfile-api-dev on behalf >> of David Lloyd >> *Sent:* Tuesday, September 30, 2025 11:07 AM >> *To:* classfile-api-dev at openjdk.org >> *Cc:* Ladislav Thon >> *Subject:* DROP_DEBUG and the constant pool >> >> We've observed that when using `DROP_DEBUG` in conjunction with >> `CodeBuilder#localVariable` and/or `localVariableType`, some (otherwise >> useless) constant pool entries are still being created (which contain, I >> believe, both the variable name and descriptor). This was observed using a >> backport of the JDK classfile API based on JDK 25. >> >> Would this be expected behavior? Is there a separate step needed to clean >> the constant pool for cases like this? >> >> It looks to me to be the consequence of how the default methods for local >> variable creation are implemented, e.g.: >> >> default CodeBuilder localVariable(int slot, String name, ClassDesc >> descriptor, Label startScope, Label endScope) { >> return localVariable(slot, >> constantPool().utf8Entry(name), >> constantPool().utf8Entry(descriptor), >> startScope, endScope); >> } >> >> The constant pool is accessed even when `DROP_DEBUG` is enabled, because >> that flag is used later on in the process, and it seems that these entries >> are never dropped, even if they are unused. >> >> -- >> - DML ? he/him >> > > > -- > - DML ? he/him > > > -- - DML ? he/him -------------- next part -------------- An HTML attachment was scrubbed... URL: From brian.goetz at oracle.com Wed Oct 1 13:16:49 2025 From: brian.goetz at oracle.com (Brian Goetz) Date: Wed, 1 Oct 2025 09:16:49 -0400 Subject: DROP_DEBUG and the constant pool In-Reply-To: References: <7105837a-dc37-41c6-851c-d20c7cc4c613@oracle.com> Message-ID: <546a8d98-cd56-42ab-ae20-df9d455446e7@oracle.com> I'm going to object to the word "fix", because I'm not convinced something is broken here.? But we can think about the implications of this change (and in the meantime, you have an entirely suitable workaround.) On 10/1/2025 9:12 AM, David Lloyd wrote: > Then perhaps the cleaner fix is instead to have the default methods > delegate to `LocalVariable.of(int,String,ClassDesc,Label,Label)` directly? > > On Wed, Oct 1, 2025 at 7:52?AM Brian Goetz wrote: > > After thinking about it for a few more minutes, I'm less sure of > this approach (and not sure I'd even classify it as a bug.)? While > locally this change is probably harmless, there are dozens of uses > of the idiom `constantPool().xxxEntry()` in this class -- why > would we switch just some of them over to using the temp pool?? > And switching all of them over falls into a more significant > change in implementation approach, for which the bar is surely > higher. > > In any case, I think we don't need to change anything; the code > you want is already in the library.? Just do > > ? ? builder.with(LocalVariable.of(slot, name, desc, start, end)) > > since that's exactly what LocalVariable::of does: > > static LocalVariable of(int slot,String name,ClassDesc descriptor,Label startScope,Label endScope) { > return of(slot, > TemporaryConstantPool.INSTANCE.utf8Entry(name), > TemporaryConstantPool.INSTANCE.utf8Entry(descriptor.descriptorString()), > startScope,endScope); > } > } > > > > > > > > > > On 10/1/2025 8:31 AM, David Lloyd wrote: >> OK, shall I prepare a bug report and patch? Thanks. >> >> On Tue, Sep 30, 2025 at 2:55?PM Chen Liang >> wrote: >> >> Hi David, this seems a legitimate bug. >> >> I think we can bypass this by using the >> TemporaryConstantPool.INSTANCE to construct the UTF-8 entries. >> >> Regards, Chen >> ------------------------------------------------------------------------ >> *From:* classfile-api-dev >> on behalf of David Lloyd >> >> *Sent:* Tuesday, September 30, 2025 11:07 AM >> *To:* classfile-api-dev at openjdk.org >> >> *Cc:* Ladislav Thon >> *Subject:* DROP_DEBUG and the constant pool >> We've observed that when using `DROP_DEBUG` in conjunction >> with `CodeBuilder#localVariable` and/or `localVariableType`, >> some (otherwise useless) constant pool entries are still >> being created (which contain, I believe, both the variable >> name and descriptor). This was observed using a backport of >> the JDK classfile API based on JDK 25. >> >> Would this be expected behavior? Is there a separate step >> needed to clean the constant pool for cases like this? >> >> It looks to me to be the consequence of how the default >> methods for local variable creation are implemented, e.g.: >> >> ? ? default CodeBuilder localVariable(int slot, String name, >> ClassDesc descriptor, Label startScope, Label endScope) { >> ? ? ? ? return localVariable(slot, >> ?constantPool().utf8Entry(name), >> ?constantPool().utf8Entry(descriptor), >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?startScope, endScope); >> ? ? } >> >> The constant pool is accessed even when `DROP_DEBUG` is >> enabled, because that flag is used later on in the process, >> and it seems that these entries are never dropped, even if >> they are unused. >> >> -- >> - DML ? he/him >> >> >> >> -- >> - DML ? he/him > > > > -- > - DML ? he/him -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.lloyd at redhat.com Wed Oct 1 13:28:30 2025 From: david.lloyd at redhat.com (David Lloyd) Date: Wed, 1 Oct 2025 08:28:30 -0500 Subject: DROP_DEBUG and the constant pool In-Reply-To: <546a8d98-cd56-42ab-ae20-df9d455446e7@oracle.com> References: <7105837a-dc37-41c6-851c-d20c7cc4c613@oracle.com> <546a8d98-cd56-42ab-ae20-df9d455446e7@oracle.com> Message-ID: OK, that's fair. But the sticking point to me is the documentation which says: "This call may be ignored if ClassFile.DebugElementsOption.DROP_DEBUG is set, or if any of the argument labels is not bound and ClassFile.DeadLabelsOption.DROP_DEAD_LABELS is set." Granted "may" is a wiggle word, but I think a reasonable reader would not interpret that as the methods taking a partial effect as they do currently; rather that it either is or is not ignored. So AFAICT *something* should be fixed, be it the code or the documentation. On Wed, Oct 1, 2025 at 8:18?AM Brian Goetz wrote: > I'm going to object to the word "fix", because I'm not convinced something > is broken here. But we can think about the implications of this change > (and in the meantime, you have an entirely suitable workaround.) > > On 10/1/2025 9:12 AM, David Lloyd wrote: > > Then perhaps the cleaner fix is instead to have the default methods > delegate to `LocalVariable.of(int,String,ClassDesc,Label,Label)` directly? > > On Wed, Oct 1, 2025 at 7:52?AM Brian Goetz wrote: > >> After thinking about it for a few more minutes, I'm less sure of this >> approach (and not sure I'd even classify it as a bug.) While locally this >> change is probably harmless, there are dozens of uses of the idiom >> `constantPool().xxxEntry()` in this class -- why would we switch just some >> of them over to using the temp pool? And switching all of them over falls >> into a more significant change in implementation approach, for which the >> bar is surely higher. >> >> In any case, I think we don't need to change anything; the code you want >> is already in the library. Just do >> >> builder.with(LocalVariable.of(slot, name, desc, start, end)) >> >> since that's exactly what LocalVariable::of does: >> >> static LocalVariable of(int slot, String name, ClassDesc descriptor, Label startScope, Label endScope) { >> return of(slot, >> TemporaryConstantPool.INSTANCE.utf8Entry(name), >> TemporaryConstantPool.INSTANCE.utf8Entry(descriptor.descriptorString()), >> startScope, endScope); >> } >> } >> >> >> >> >> >> >> >> >> >> >> On 10/1/2025 8:31 AM, David Lloyd wrote: >> >> OK, shall I prepare a bug report and patch? Thanks. >> >> On Tue, Sep 30, 2025 at 2:55?PM Chen Liang >> wrote: >> >>> Hi David, this seems a legitimate bug. >>> >>> I think we can bypass this by using the TemporaryConstantPool.INSTANCE >>> to construct the UTF-8 entries. >>> >>> Regards, Chen >>> ------------------------------ >>> *From:* classfile-api-dev on >>> behalf of David Lloyd >>> *Sent:* Tuesday, September 30, 2025 11:07 AM >>> *To:* classfile-api-dev at openjdk.org >>> *Cc:* Ladislav Thon >>> *Subject:* DROP_DEBUG and the constant pool >>> >>> We've observed that when using `DROP_DEBUG` in conjunction with >>> `CodeBuilder#localVariable` and/or `localVariableType`, some (otherwise >>> useless) constant pool entries are still being created (which contain, I >>> believe, both the variable name and descriptor). This was observed using a >>> backport of the JDK classfile API based on JDK 25. >>> >>> Would this be expected behavior? Is there a separate step needed to >>> clean the constant pool for cases like this? >>> >>> It looks to me to be the consequence of how the default methods for >>> local variable creation are implemented, e.g.: >>> >>> default CodeBuilder localVariable(int slot, String name, ClassDesc >>> descriptor, Label startScope, Label endScope) { >>> return localVariable(slot, >>> constantPool().utf8Entry(name), >>> constantPool().utf8Entry(descriptor), >>> startScope, endScope); >>> } >>> >>> The constant pool is accessed even when `DROP_DEBUG` is enabled, because >>> that flag is used later on in the process, and it seems that these entries >>> are never dropped, even if they are unused. >>> >>> -- >>> - DML ? he/him >>> >> >> >> -- >> - DML ? he/him >> >> >> > > -- > - DML ? he/him > > > -- - DML ? he/him -------------- next part -------------- An HTML attachment was scrubbed... URL: From chen.l.liang at oracle.com Wed Oct 1 14:18:03 2025 From: chen.l.liang at oracle.com (Chen Liang) Date: Wed, 1 Oct 2025 14:18:03 +0000 Subject: [External] : Re: DROP_DEBUG and the constant pool In-Reply-To: References: <7105837a-dc37-41c6-851c-d20c7cc4c613@oracle.com> <546a8d98-cd56-42ab-ae20-df9d455446e7@oracle.com> Message-ID: I considered this a bug because Class-File API intentionally prevents generating redundant CP entries elsewhere, such as in StackMapGenerator. (Using ClassDesc instead of ClassEntry for stack map type tracking) I used "may" in the original spec because this is ignored for DirectCodeBuilder, but not ignored for Buffered/ChainedCodeBuilder used in transforms. If we dig down the rabbit hole, we may argue that exceptionCatch is a candidate too - we might skip ones that are dead, but they already create CP entries. As Brian said, there are workarounds - if you are transforming to drop debug elements, you should use a new constant pool to deduplicate. If you are building, you can skip the call yourself. I think the only scenario in which this matters is when you are transforming someone else's code as in CodeBuilder.transforming. What exactly is your use case that makes this problem apparent? Chen ________________________________ From: David Lloyd Sent: Wednesday, October 1, 2025 8:28 AM To: Brian Goetz Cc: Chen Liang ; classfile-api-dev at openjdk.org ; Ladislav Thon Subject: [External] : Re: DROP_DEBUG and the constant pool OK, that's fair. But the sticking point to me is the documentation which says: "This call may be ignored if ClassFile.DebugElementsOption.DROP_DEBUG is set, or if any of the argument labels is not bound and ClassFile.DeadLabelsOption.DROP_DEAD_LABELS is set." Granted "may" is a wiggle word, but I think a reasonable reader would not interpret that as the methods taking a partial effect as they do currently; rather that it either is or is not ignored. So AFAICT *something* should be fixed, be it the code or the documentation. On Wed, Oct 1, 2025 at 8:18?AM Brian Goetz > wrote: I'm going to object to the word "fix", because I'm not convinced something is broken here. But we can think about the implications of this change (and in the meantime, you have an entirely suitable workaround.) On 10/1/2025 9:12 AM, David Lloyd wrote: Then perhaps the cleaner fix is instead to have the default methods delegate to `LocalVariable.of(int,String,ClassDesc,Label,Label)` directly? On Wed, Oct 1, 2025 at 7:52?AM Brian Goetz > wrote: After thinking about it for a few more minutes, I'm less sure of this approach (and not sure I'd even classify it as a bug.) While locally this change is probably harmless, there are dozens of uses of the idiom `constantPool().xxxEntry()` in this class -- why would we switch just some of them over to using the temp pool? And switching all of them over falls into a more significant change in implementation approach, for which the bar is surely higher. In any case, I think we don't need to change anything; the code you want is already in the library. Just do builder.with(LocalVariable.of(slot, name, desc, start, end)) since that's exactly what LocalVariable::of does: static LocalVariable of(int slot, String name, ClassDesc descriptor, Label startScope, Label endScope) { return of(slot, TemporaryConstantPool.INSTANCE.utf8Entry(name), TemporaryConstantPool.INSTANCE.utf8Entry(descriptor.descriptorString()), startScope, endScope); } } On 10/1/2025 8:31 AM, David Lloyd wrote: OK, shall I prepare a bug report and patch? Thanks. On Tue, Sep 30, 2025 at 2:55?PM Chen Liang > wrote: Hi David, this seems a legitimate bug. I think we can bypass this by using the TemporaryConstantPool.INSTANCE to construct the UTF-8 entries. Regards, Chen ________________________________ From: classfile-api-dev > on behalf of David Lloyd > Sent: Tuesday, September 30, 2025 11:07 AM To: classfile-api-dev at openjdk.org > Cc: Ladislav Thon > Subject: DROP_DEBUG and the constant pool We've observed that when using `DROP_DEBUG` in conjunction with `CodeBuilder#localVariable` and/or `localVariableType`, some (otherwise useless) constant pool entries are still being created (which contain, I believe, both the variable name and descriptor). This was observed using a backport of the JDK classfile API based on JDK 25. Would this be expected behavior? Is there a separate step needed to clean the constant pool for cases like this? It looks to me to be the consequence of how the default methods for local variable creation are implemented, e.g.: default CodeBuilder localVariable(int slot, String name, ClassDesc descriptor, Label startScope, Label endScope) { return localVariable(slot, constantPool().utf8Entry(name), constantPool().utf8Entry(descriptor), startScope, endScope); } The constant pool is accessed even when `DROP_DEBUG` is enabled, because that flag is used later on in the process, and it seems that these entries are never dropped, even if they are unused. -- - DML ? he/him -- - DML ? he/him -- - DML ? he/him -- - DML ? he/him -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.lloyd at redhat.com Wed Oct 1 14:23:09 2025 From: david.lloyd at redhat.com (David Lloyd) Date: Wed, 1 Oct 2025 09:23:09 -0500 Subject: [External] : Re: DROP_DEBUG and the constant pool In-Reply-To: References: <7105837a-dc37-41c6-851c-d20c7cc4c613@oracle.com> <546a8d98-cd56-42ab-ae20-df9d455446e7@oracle.com> Message-ID: We generate some fairly complex code, and we wanted to introduce a switch to disable debug output. Setting this flag seemed like a simple solution, but it didn't fully work out that way, which was unexpected. As you and Brian have said, there are multiple possible workarounds, so we are not stuck by any means. On Wed, Oct 1, 2025 at 9:18?AM Chen Liang wrote: > I considered this a bug because Class-File API intentionally prevents > generating redundant CP entries elsewhere, such as in StackMapGenerator. > (Using ClassDesc instead of ClassEntry for stack map type tracking) > I used "may" in the original spec because this is ignored for > DirectCodeBuilder, but not ignored for Buffered/ChainedCodeBuilder used in > transforms. > If we dig down the rabbit hole, we may argue that exceptionCatch is a > candidate too - we might skip ones that are dead, but they already create > CP entries. > > As Brian said, there are workarounds - if you are transforming to drop > debug elements, you should use a new constant pool to deduplicate. If you > are building, you can skip the call yourself. I think the only scenario in > which this matters is when you are transforming someone else's code as in > CodeBuilder.transforming. What exactly is your use case that makes this > problem apparent? > > Chen > ------------------------------ > *From:* David Lloyd > *Sent:* Wednesday, October 1, 2025 8:28 AM > *To:* Brian Goetz > *Cc:* Chen Liang ; classfile-api-dev at openjdk.org > ; Ladislav Thon > *Subject:* [External] : Re: DROP_DEBUG and the constant pool > > OK, that's fair. But the sticking point to me is the documentation which > says: "This call may be ignored if ClassFile.DebugElementsOption.DROP_DEBUG > is set, or if any of the argument labels is not bound and > ClassFile.DeadLabelsOption.DROP_DEAD_LABELS is set." Granted "may" is a > wiggle word, but I think a reasonable reader would not interpret that as > the methods taking a partial effect as they do currently; rather that it > either is or is not ignored. So AFAICT *something* should be fixed, be it > the code or the documentation. > > On Wed, Oct 1, 2025 at 8:18?AM Brian Goetz wrote: > > I'm going to object to the word "fix", because I'm not convinced something > is broken here. But we can think about the implications of this change > (and in the meantime, you have an entirely suitable workaround.) > > On 10/1/2025 9:12 AM, David Lloyd wrote: > > Then perhaps the cleaner fix is instead to have the default methods > delegate to `LocalVariable.of(int,String,ClassDesc,Label,Label)` directly? > > On Wed, Oct 1, 2025 at 7:52?AM Brian Goetz wrote: > > After thinking about it for a few more minutes, I'm less sure of this > approach (and not sure I'd even classify it as a bug.) While locally this > change is probably harmless, there are dozens of uses of the idiom > `constantPool().xxxEntry()` in this class -- why would we switch just some > of them over to using the temp pool? And switching all of them over falls > into a more significant change in implementation approach, for which the > bar is surely higher. > > In any case, I think we don't need to change anything; the code you want > is already in the library. Just do > > builder.with(LocalVariable.of(slot, name, desc, start, end)) > > since that's exactly what LocalVariable::of does: > > static LocalVariable of(int slot, String name, ClassDesc descriptor, Label startScope, Label endScope) { > return of(slot, > TemporaryConstantPool.INSTANCE.utf8Entry(name), > TemporaryConstantPool.INSTANCE.utf8Entry(descriptor.descriptorString()), > startScope, endScope); > } > } > > > > > > > > > > > On 10/1/2025 8:31 AM, David Lloyd wrote: > > OK, shall I prepare a bug report and patch? Thanks. > > On Tue, Sep 30, 2025 at 2:55?PM Chen Liang > wrote: > > Hi David, this seems a legitimate bug. > > I think we can bypass this by using the TemporaryConstantPool.INSTANCE to > construct the UTF-8 entries. > > Regards, Chen > ------------------------------ > *From:* classfile-api-dev on behalf > of David Lloyd > *Sent:* Tuesday, September 30, 2025 11:07 AM > *To:* classfile-api-dev at openjdk.org > *Cc:* Ladislav Thon > *Subject:* DROP_DEBUG and the constant pool > > We've observed that when using `DROP_DEBUG` in conjunction with > `CodeBuilder#localVariable` and/or `localVariableType`, some (otherwise > useless) constant pool entries are still being created (which contain, I > believe, both the variable name and descriptor). This was observed using a > backport of the JDK classfile API based on JDK 25. > > Would this be expected behavior? Is there a separate step needed to clean > the constant pool for cases like this? > > It looks to me to be the consequence of how the default methods for local > variable creation are implemented, e.g.: > > default CodeBuilder localVariable(int slot, String name, ClassDesc > descriptor, Label startScope, Label endScope) { > return localVariable(slot, > constantPool().utf8Entry(name), > constantPool().utf8Entry(descriptor), > startScope, endScope); > } > > The constant pool is accessed even when `DROP_DEBUG` is enabled, because > that flag is used later on in the process, and it seems that these entries > are never dropped, even if they are unused. > > -- > - DML ? he/him > > > > -- > - DML ? he/him > > > > > -- > - DML ? he/him > > > > > -- > - DML ? he/him > -- - DML ? he/him -------------- next part -------------- An HTML attachment was scrubbed... URL: