Skip to content

Conversation

@popematt
Copy link
Contributor

Description of changes:

Adds Ion 1.0 bytecode generator for a fixed-sized, in-memory data stream.
Previous benchmarks suggest that this may provide ~10% more throughput than the current continuable reader for the use-case that this bytecode generator supports.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@popematt popematt requested a review from tgregg November 10, 2025 21:56
@popematt popematt marked this pull request as draft November 10, 2025 22:14
@codecov
Copy link

codecov bot commented Nov 10, 2025

Codecov Report

❌ Patch coverage is 90.51724% with 22 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (ion11@359db5a). Learn more about missing BASE report.

Files with missing lines Patch % Lines
...ion/bytecode/bin10/ByteArrayBytecodeGenerator10.kt 90.14% 8 Missing and 13 partials ⚠️
...java/com/amazon/ion/bytecode/bin10/TypeIdHelper.kt 94.44% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             ion11    #1143   +/-   ##
========================================
  Coverage         ?   69.97%           
  Complexity       ?     6595           
========================================
  Files            ?      211           
  Lines            ?    26554           
  Branches         ?     4596           
========================================
  Hits             ?    18582           
  Misses           ?     6533           
  Partials         ?     1439           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@popematt popematt marked this pull request as ready for review November 10, 2025 22:33
Comment on lines 82 to 83
// TODO(perf): See if there's a way to do this without allocating new ByteBuffers, that is compatible with JDK 8.
val buffer = ByteBuffer.wrap(source, position, length)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should just be able to wrap the source once, then change its position and limit here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's something weird going on with those methods. I can see them in the JDK 8 javadoc, but I think later JDKs have ByteBuffer override the base method in Buffer, and it was causing issue in the tests running on JDK 8. I'll revisit it and see if I can fix the problem some other way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh... I followed the reusable ByteBuffer pattern in the continuable reader. Not sure what would be different here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could possibly have to do the difference between invoking the method on the parent class vs on the child class.

if (TypeIdHelper.isNull(typeId)) {
compileNullValue(typeId, dest)
} else when (TypeIdHelper.operationKindForTypeId(typeId)) {
OperationKind.UNSET -> if (isAnnotated) throw IonException("Invalid annotation wrapper: NOP pad may not occur inside an annotation wrapper.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the relevant error message to all situations where this can occur?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it is relevant any time you have an NOP for which isAnnotated is true. Is there some other case that I'm missing here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess my question was about whether UNSET is only used for NOP. I think you're saying that it is, and therefore the error message is correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is. I'm using -1 for "not a valid type id", so there is nothing else here that is using UNSET. It might be worth revisiting this later to see if we can rename it NOP.

I_STRUCT_START withData 6,
I_FIELD_NAME_SID withData 4,
I_NULL_NULL,
I_FIELD_NAME_SID withData 5,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm assuming the field name associated with the no-op is present here because it's faster not to add a check to elide it in this rare case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.

@popematt popematt merged commit b574fdb into amazon-ion:ion11 Nov 11, 2025
26 of 36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants