Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: Remove all static strings, shrink Value structs #19716

Merged
merged 11 commits into from
Mar 9, 2025

Conversation

Lord-McSweeney
Copy link
Collaborator

AvmString now directly holds a Gc<AvmStringRepr>, which shrinks Value structs on 64-bit from 24 to 16 bytes. getlocal, setlocal, and getslot run 5-10% faster; Chess Demons starts up about 5% faster.

@Lord-McSweeney Lord-McSweeney added A-avm2 Area: AVM2 (ActionScript 3) A-avm1 Area: AVM1 (ActionScript 1 & 2) T-perf Type: Performance Improvements labels Mar 5, 2025
@@ -595,8 +548,6 @@ pub fn load_player_globals<'gc>(

globals.set_vtable(mc, global_obj_vtable);

activation.context.avm2.toplevel_global_object = Some(globals);
Copy link
Collaborator

@adrian17 adrian17 Mar 6, 2025

Choose a reason for hiding this comment

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

To be sure, why was this moved later?

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 have three script global objects right now- one for the builtin classes script, one for Toplevel.as, and one for globals.as. The "toplevel" global object has pointed to the builtin one for a long time, but as we moved classes out of it and into Toplevel.as it makes more sense to make it point to the Toplevel.as global object.

The hacky part was that some tests depended on the "toplevel" global object having the parseInt, parseFloat, etc properties, which, since they were defined in Toplevel.as, we had to copy over to the builtin global object manually. Now that the only properties left on the builtin global object are Object and Class anyway, I made the "toplevel" global object point to Toplevel.as and removed the copying hack.

@@ -290,7 +290,7 @@ impl<'gc> Domain<'gc> {
activation.gc(),
&name[(start + 2)..(name.len() - 1)],
));
name = "__AS3__.vec::Vector".into();
name = AvmString::new_utf8(activation.gc(), "__AS3__.vec::Vector");
Copy link
Collaborator

Choose a reason for hiding this comment

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

This could still be an AvmString-pointing-to-static, right?

@@ -100,8 +103,9 @@ pub fn create_c_class<'gc>(
let gc_context = activation.gc();
let namespaces = activation.avm2().namespaces;

let class_name = AvmString::new_utf8(gc_context, "Class$");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Managed-pointing-to-static?

@adrian17
Copy link
Collaborator

adrian17 commented Mar 6, 2025

So a lot of these AvmString::new_utf8(gc_context, "Class$"); could be replaced with managed-static strings, with the only caveat being that... we don't really have an API for these, aside from intern_static which also implies interning?
I'm okay with some kind of new_xyz_static(gc, s: &'static str / &'static [u8]) being out of this PR, but let's make sure this is indeed what we want in the long run.

Also after this gets merged, I'll do an instrumented test to see what dynamic strings we now allocate from our own code during normal runtime.

@Lord-McSweeney Lord-McSweeney force-pushed the no-istr branch 2 times, most recently from 17c9bc0 to 45c741e Compare March 8, 2025 19:28
const _: () = assert!(size_of::<Value<'_>>() <= 16);

#[cfg(target_pointer_width = "64")]
const _: () = assert!(size_of::<Value<'_>>() == 24);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you keep them separate, to be more explicit? Will be also useful if we ever do NaN boxing on 32-bit.

@@ -38,12 +38,8 @@ impl Debug for Error<'_> {
}

// This type is used very frequently, so make sure it doesn't unexpectedly grow.
#[cfg(target_family = "wasm")]
const _: () = assert!(size_of::<Result<Value<'_>, Error<'_>>>() == 24);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I thought that the size is smaller (16?) on non-wasm due to x86 being less strict with alignment?
At least at some point it was. Do we do any testing on 32-bit?

That's why I suggest keeping them separate here too.

@Lord-McSweeney Lord-McSweeney enabled auto-merge (rebase) March 9, 2025 14:51
@Lord-McSweeney Lord-McSweeney merged commit 884563b into ruffle-rs:master Mar 9, 2025
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-avm1 Area: AVM1 (ActionScript 1 & 2) A-avm2 Area: AVM2 (ActionScript 3) T-perf Type: Performance Improvements
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants