Skip to content

Commit daab8f5

Browse files
committed
avm1: Small optimizations for Object::is_instance_of
- don't make a copy of the `Object.interfaces` vec; - use `SmallVec` to reduce allocations in the common case - of empty or non-branching interface trees.
1 parent 67cc2b2 commit daab8f5

File tree

2 files changed

+9
-10
lines changed

2 files changed

+9
-10
lines changed

core/src/avm1/object.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ impl<'gc> Object<'gc> {
320320
// TODO(moulins): should we guard against infinite loops here?
321321
// A recursive prototype and/or interface chain will hang Flash Player.
322322

323-
let mut interface_stack = vec![];
323+
let mut interface_stack = smallvec::SmallVec::<[_; 4]>::new();
324324
let mut this = self;
325325

326326
while let Value::Object(this_proto) = this.proto(activation) {
@@ -331,7 +331,7 @@ impl<'gc> Object<'gc> {
331331
return Ok(true);
332332
}
333333

334-
interface_stack.extend(interface.interfaces());
334+
interface_stack.extend(interface.interfaces().iter().cloned());
335335
}
336336

337337
this = this_proto;

core/src/avm1/object/script_object.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use core::{fmt, mem};
1313
use gc_arena::lock::RefLock;
1414
use gc_arena::{Collect, DynamicRoot, Gc, GcWeak, Mutation, Rootable};
1515
use ruffle_macros::istr;
16+
use std::cell::Ref;
1617

1718
use super::super_object::SuperObject;
1819

@@ -800,20 +801,18 @@ impl<'gc> Object<'gc> {
800801
}
801802

802803
/// Enumerate all interfaces implemented by this object.
803-
pub(super) fn interfaces(self) -> Vec<Object<'gc>> {
804-
if self.as_super_object().is_some() {
805-
// `super` does not implement interfaces
806-
return vec![];
807-
}
808-
809-
self.0.borrow().interfaces.clone().unwrap_or_default()
804+
pub(super) fn interfaces(self) -> Ref<'gc, [Object<'gc>]> {
805+
Ref::map(self.0.borrow(), |this| match &this.interfaces {
806+
Some(slice) => slice.as_slice(),
807+
None => &[],
808+
})
810809
}
811810

812811
/// Set the interface list for this object. (Only useful for prototypes.)
813812
/// Calling this a second time will have no effect.
814813
pub fn set_interfaces(self, gc_context: &Mutation<'gc>, iface_list: Vec<Object<'gc>>) {
815814
if self.as_super_object().is_some() {
816-
// `super` probably cannot have interfaces set on it
815+
// `super` cannot have interfaces set on it
817816
return;
818817
}
819818

0 commit comments

Comments
 (0)