From ae956eb10f93776ed027097da367f08fa61c4e39 Mon Sep 17 00:00:00 2001 From: Lord-McSweeney Date: Thu, 12 Sep 2024 23:28:36 -0700 Subject: [PATCH] avm2: Avoid unnecessary Gc allocation for `PropertyClass::Name` --- core/src/avm2/property.rs | 27 +++++++++------------------ core/src/avm2/vtable.rs | 4 ++-- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/core/src/avm2/property.rs b/core/src/avm2/property.rs index af4043812..04f0ff98a 100644 --- a/core/src/avm2/property.rs +++ b/core/src/avm2/property.rs @@ -7,7 +7,7 @@ use crate::avm2::TranslationUnit; use crate::avm2::Value; use crate::context::GcContext; use crate::string::AvmString; -use gc_arena::{Collect, Gc, Mutation}; +use gc_arena::{Collect, Gc}; use super::class::Class; @@ -36,22 +36,17 @@ pub enum Property { #[derive(Collect, Clone, Copy)] #[collect(no_drop)] pub enum PropertyClass<'gc> { - /// The type `*` (Multiname::is_any()). This allows - /// `Value::Undefined`, so it needs to be distinguished - /// from the `Object` class + /// The type `*`. This allows `Value::Undefined`, so it needs to + /// be distinguished from the `Object` class Any, Class(Class<'gc>), - Name(Gc<'gc, (Gc<'gc, Multiname<'gc>>, Option>)>), + Name(Gc<'gc, Multiname<'gc>>, Option>), } impl<'gc> PropertyClass<'gc> { - pub fn name( - mc: &Mutation<'gc>, - name: Option>>, - unit: Option>, - ) -> Self { + pub fn name(name: Option>>, unit: Option>) -> Self { if let Some(name) = name { - PropertyClass::Name(Gc::new(mc, (name, unit))) + PropertyClass::Name(name, unit) } else { PropertyClass::Any } @@ -67,9 +62,7 @@ impl<'gc> PropertyClass<'gc> { ) -> Result<(Value<'gc>, bool), Error<'gc>> { let (class, changed) = match self { PropertyClass::Class(class) => (Some(*class), false), - PropertyClass::Name(gc) => { - let (name, unit) = &**gc; - + PropertyClass::Name(name, unit) => { // Note - we look up the class in the domain by name, which allows us to look up private classes. // This also has the advantage of letting us coerce to a class while the `ClassObject` // is still being constructed (since the `Class` will already exist in the domain). @@ -104,9 +97,7 @@ impl<'gc> PropertyClass<'gc> { ) -> Result>, Error<'gc>> { match self { PropertyClass::Class(class) => Ok(Some(*class)), - PropertyClass::Name(gc) => { - let (name, unit) = &**gc; - + PropertyClass::Name(name, unit) => { let domain = unit.map_or(activation.avm2().playerglobals_domain, |u| u.domain()); if let Some(class) = domain.get_class(activation.context, name) { *self = PropertyClass::Class(class); @@ -125,7 +116,7 @@ impl<'gc> PropertyClass<'gc> { pub fn get_name(&self, context: &mut GcContext<'_, 'gc>) -> AvmString<'gc> { match self { PropertyClass::Class(class) => class.name().to_qualified_name(context.gc_context), - PropertyClass::Name(gc) => gc.0.to_qualified_name_or_star(context), + PropertyClass::Name(name, _) => name.to_qualified_name_or_star(context), PropertyClass::Any => context.interner.get_ascii_char('*'), } } diff --git a/core/src/avm2/vtable.rs b/core/src/avm2/vtable.rs index f6f73d57f..158b09ec2 100644 --- a/core/src/avm2/vtable.rs +++ b/core/src/avm2/vtable.rs @@ -461,13 +461,13 @@ impl<'gc> VTable<'gc> { type_name, unit, .. } => ( Property::new_slot(new_slot_id), - PropertyClass::name(mc, *type_name, *unit), + PropertyClass::name(*type_name, *unit), ), TraitKind::Const { type_name, unit, .. } => ( Property::new_const_slot(new_slot_id), - PropertyClass::name(mc, *type_name, *unit), + PropertyClass::name(*type_name, *unit), ), TraitKind::Class { class, .. } => ( Property::new_const_slot(new_slot_id),