Skip to content
This repository has been archived by the owner on Mar 20, 2024. It is now read-only.

Extend entrypoint generation to handle multi-module packages #374

Merged
merged 1 commit into from Sep 21, 2023

Conversation

dmakarov
Copy link
Collaborator

@dmakarov dmakarov commented Sep 19, 2023

Motivation

Current generation of entrypoint glue code works only for packages with entry functions defined in a single module. These changes move entrypoint glue code generation outside ModuleContext. The glue code is generated in a separate LLVM module, so that it can make calls to entry functions defined in any module of a package.

Test Plan

Added rbpf-tests test with entry functions in different modules.

Resolves #369

@dmakarov dmakarov force-pushed the dm/altentry branch 5 times, most recently from 49797b2 to 40683a7 Compare September 19, 2023 21:05
@@ -1,5 +1,5 @@
#[test_only]
module std::fixed_point32_tests {
module std::fp32_tests {
use std::fixed_point32;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This change of name is to pass the 64 char limit on external symbol length imposed by the Solana VM.

// NB: context must outlive llvm module
// fixme this should be handled with lifetimes
// FIXME: this should be handled with lifetimes.
// Context (global_cx) must outlive llvm module (entry_llmod).
Copy link
Collaborator

Choose a reason for hiding this comment

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

@brson's expertise is needed here.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'll give it a look.

Copy link
Collaborator

@brson brson Sep 20, 2023

Choose a reason for hiding this comment

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

I filed an issue with a potential fix for this #379

I don't think it should hold up this pr, as this pr is just continuing the existing pattern of manually managing the lifetime of the llvm mod.

Copy link
Collaborator

@brson brson Sep 20, 2023

Choose a reason for hiding this comment

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

fwiw I also recall thinking that the original scheme for managing lifetimes of these contexts, with the 'mm and 'up lifetimes, is probably wrong, though I don't remember why. Anyway, that scheme appears to still be working for now.

* requested entry function to be passed in instruction_data byte
* array. The logic in solana entrypoint iteratively compares the
* string slice passed in instruction_data to every entry function
* symbol of the module. Once a matching entry function is found,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a chance that the list of entry functions can have duplicates?

Copy link
Collaborator

Choose a reason for hiding this comment

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

or ODR takes care of it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

if two modules have the same name and they both contain entry functions with the same name, then yes there will be duplicates. We probably will include modules’ unique addresses in function names to avoid conflicts.

Copy link
Collaborator

Choose a reason for hiding this comment

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

maybe it will help to assert that there are no two duplicates. at least in debug mode?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I added a debug_assert!() to check for duplicate entry function names.

let level = record.level();
let mut style = formatter.style();
match record.level() {
Level::Error => style.set_color(Color::Red),
Copy link
Collaborator

Choose a reason for hiding this comment

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

nice! how do we test the logger?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We could probably write tests checking the log messages. Is it worth the effort at the moment? I added this initializer for consistency with move-cli code path, as previously the logger was initialized when global context was created which is too late and wrong (https://github.com/jcivlin/move/blame/599dbfbecc6d8b8893ee9c683b402e740f1f9820/language/tools/move-mv-llvm-compiler/src/stackless/translate.rs#L121-L142). I mentioned previously, I'd like to decommission move-mv-llvm-compiler as it will never be used by the end users, it is only used for testing at the moment, and it is taking wasted efforts to maintain.

Copy link
Collaborator

Choose a reason for hiding this comment

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

not necessary to write test for it atm. i'll just create an issue for this and move on. #377

@dmakarov dmakarov force-pushed the dm/altentry branch 2 times, most recently from 9c35610 to 56f7cde Compare September 20, 2023 12:10
llvm_module: &'up llvm::Module,
rtty_cx: &RttyContext,
val: u64,
) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This and several other methods need to be used by EntrypointGenerator which has its own LLVM module that isn't included in an existing ModuleContext, therefore I tried to reuse the code by converting these methods to 'class'-level methods instead of 'instance'-level. Maybe some other refactoring is needed to have a better design and code reuse. I would appreciate suggestions how to improve this.

Copy link
Collaborator

Choose a reason for hiding this comment

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

as long as it is helping you make progress, i guess this is fine. Maybe we can just write a comment here (as TODO?) or have a task and move on.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added a comment.

test_signers: args.test_signers.clone(),
..MoveToSolanaOptions::default()
};
let entry_llmod = global_cx.llvm_cx.create_module("solana_entrypoint");
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: i feel like we need a file with all these constants (e.g. solana_entrypoint) which can be reused. As in language/tools/move-mv-llvm-compiler/tests/rbpf-tests.rs where we have solana_entrypoint.o

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I agree, although rbpf-tests.rs is exposed to too many internals of compiler at the moment. This specific string is supposed to be hidden in move-to-solana/lib.rs only, where it should be defined as a compile time constant, probably.

Copy link
Collaborator

@brson brson left a comment

Choose a reason for hiding this comment

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

I'm fine with all this assuming @ksolana's is satisfied.

@dmakarov dmakarov merged commit 6716e0e into anza-xyz:llvm-sys Sep 21, 2023
8 checks passed
@dmakarov dmakarov deleted the dm/altentry branch September 21, 2023 12:14
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug] Support compiling a multimodule package with entry functions in multiple modules
3 participants