Skip to content

Commit e518600

Browse files
committed
Some more getattr related tweaks/optimizations
1 parent 3d3889f commit e518600

File tree

7 files changed

+35
-39
lines changed

7 files changed

+35
-39
lines changed

bytecode/src/bytecode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ impl Label {
9191
}
9292
}
9393

94-
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
94+
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
9595
/// An indication where the name must be accessed.
9696
pub enum NameScope {
9797
/// The name will be in the local scope.

vm/src/frame.rs

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,17 @@ use crate::common::cell::PyMutex;
1010
use crate::exceptions::{self, ExceptionCtor, PyBaseExceptionRef};
1111
use crate::function::PyFuncArgs;
1212
use crate::obj::objasyncgenerator::PyAsyncGenWrappedValue;
13-
use crate::obj::objbool;
1413
use crate::obj::objcode::PyCodeRef;
1514
use crate::obj::objcoroinner::Coro;
1615
use crate::obj::objcoroutine::PyCoroutine;
1716
use crate::obj::objdict::{PyDict, PyDictRef};
1817
use crate::obj::objgenerator::PyGenerator;
19-
use crate::obj::objiter;
20-
use crate::obj::objlist;
2118
use crate::obj::objslice::PySlice;
2219
use crate::obj::objstr::{self, PyStr, PyStrRef};
2320
use crate::obj::objtraceback::PyTraceback;
2421
use crate::obj::objtuple::PyTuple;
2522
use crate::obj::objtype::{self, PyTypeRef};
23+
use crate::obj::{objbool, objiter, objlist, objset};
2624
use crate::pyobject::{
2725
BorrowValue, IdProtocol, ItemProtocol, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
2826
TypeProtocol,
@@ -177,6 +175,7 @@ impl Frame {
177175
}
178176

179177
impl FrameRef {
178+
#[inline]
180179
fn with_exec<R>(&self, f: impl FnOnce(ExecutingFrame) -> R) -> R {
181180
let mut state = self.state.lock();
182181
let exec = ExecutingFrame {
@@ -350,14 +349,10 @@ impl ExecutingFrame<'_> {
350349
} => self.import(vm, name, symbols, *level),
351350
bytecode::Instruction::ImportStar => self.import_star(vm),
352351
bytecode::Instruction::ImportFrom { ref name } => self.import_from(vm, name),
353-
bytecode::Instruction::LoadName {
354-
ref name,
355-
ref scope,
356-
} => self.load_name(vm, name, scope),
357-
bytecode::Instruction::StoreName {
358-
ref name,
359-
ref scope,
360-
} => self.store_name(vm, name, scope),
352+
bytecode::Instruction::LoadName { ref name, scope } => self.load_name(vm, name, *scope),
353+
bytecode::Instruction::StoreName { ref name, scope } => {
354+
self.store_name(vm, name, *scope)
355+
}
361356
bytecode::Instruction::DeleteName { ref name } => self.delete_name(vm, name),
362357
bytecode::Instruction::Subscript => self.execute_subscript(vm),
363358
bytecode::Instruction::StoreSubscript => self.execute_store_subscript(vm),
@@ -393,11 +388,11 @@ impl ExecutingFrame<'_> {
393388
}
394389
bytecode::Instruction::BuildSet { size, unpack } => {
395390
let elements = self.get_elements(vm, *size, *unpack)?;
396-
let py_obj = vm.ctx.new_set();
391+
let set = vm.ctx.new_set();
397392
for item in elements {
398-
vm.call_method(&py_obj, "add", vec![item])?;
393+
set.add(item, vm)?;
399394
}
400-
self.push_value(py_obj);
395+
self.push_value(set.into_object());
401396
Ok(None)
402397
}
403398
bytecode::Instruction::BuildTuple { size, unpack } => {
@@ -421,22 +416,22 @@ impl ExecutingFrame<'_> {
421416
bytecode::Instruction::SetAdd { i } => {
422417
let set_obj = self.nth_value(*i);
423418
let item = self.pop_value();
424-
vm.call_method(&set_obj, "add", vec![item])?;
419+
objset::PySetRef::try_from_object(vm, set_obj)?.add(item, vm)?;
425420
Ok(None)
426421
}
427422
bytecode::Instruction::MapAdd { i } => {
428423
let dict_obj = self.nth_value(*i + 1);
429424
let key = self.pop_value();
430425
let value = self.pop_value();
431-
vm.call_method(&dict_obj, "__setitem__", vec![key, value])?;
426+
PyDictRef::try_from_object(vm, dict_obj)?.set_item(key, value, vm)?;
432427
Ok(None)
433428
}
434429
bytecode::Instruction::MapAddRev { i } => {
435430
// change order of evalutio of key and value to support Py3.8 Named expressions in dict comprehension
436431
let dict_obj = self.nth_value(*i + 1);
437432
let value = self.pop_value();
438433
let key = self.pop_value();
439-
vm.call_method(&dict_obj, "__setitem__", vec![key, value])?;
434+
PyDictRef::try_from_object(vm, dict_obj)?.set_item(key, value, vm)?;
440435
Ok(None)
441436
}
442437
bytecode::Instruction::BinaryOperation { ref op, inplace } => {
@@ -882,7 +877,7 @@ impl ExecutingFrame<'_> {
882877
&mut self,
883878
vm: &VirtualMachine,
884879
name: &str,
885-
name_scope: &bytecode::NameScope,
880+
name_scope: bytecode::NameScope,
886881
) -> FrameResult {
887882
let obj = self.pop_value();
888883
match name_scope {
@@ -910,11 +905,12 @@ impl ExecutingFrame<'_> {
910905
}
911906

912907
#[cfg_attr(feature = "flame-it", flame("Frame"))]
908+
#[inline]
913909
fn load_name(
914910
&mut self,
915911
vm: &VirtualMachine,
916912
name: &str,
917-
name_scope: &bytecode::NameScope,
913+
name_scope: bytecode::NameScope,
918914
) -> FrameResult {
919915
let optional_value = match name_scope {
920916
bytecode::NameScope::Global => self.scope.load_global(vm, name),
@@ -1210,8 +1206,7 @@ impl ExecutingFrame<'_> {
12101206

12111207
fn jump(&mut self, label: bytecode::Label) {
12121208
let target_pc = self.code.label_map[&label];
1213-
#[cfg(feature = "vm-tracing-logging")]
1214-
trace!("jump from {:?} to {:?}", self.lasti(), target_pc);
1209+
vm_trace!("jump from {:?} to {:?}", self.lasti(), target_pc);
12151210
self.lasti.store(target_pc, Ordering::Relaxed);
12161211
}
12171212

vm/src/obj/objdict.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ impl PyDict {
388388
Ok(PyDict { entries: dict })
389389
}
390390

391-
pub fn contains_key<T: IntoPyObject>(&self, key: T, vm: &VirtualMachine) -> bool {
391+
pub fn contains_key<K: IntoPyObject>(&self, key: K, vm: &VirtualMachine) -> bool {
392392
let key = key.into_pyobject(vm);
393393
self.entries.contains(vm, &key).unwrap()
394394
}
@@ -421,6 +421,7 @@ impl Unhashable for PyDict {}
421421

422422
impl PyDictRef {
423423
/// Return an optional inner item, or an error (can be key error as well)
424+
#[inline]
424425
fn inner_getitem_option<K: DictKey>(
425426
&self,
426427
key: K,
@@ -453,9 +454,9 @@ impl PyDictRef {
453454
/// python value, or None.
454455
/// Note that we can pass any type which implements the DictKey
455456
/// trait. Notable examples are String and PyObjectRef.
456-
pub fn get_item_option<T: IntoPyObject + DictKey>(
457+
pub fn get_item_option<K: IntoPyObject + DictKey>(
457458
&self,
458-
key: T,
459+
key: K,
459460
vm: &VirtualMachine,
460461
) -> PyResult<Option<PyObjectRef>> {
461462
// Test if this object is a true dict, or mabye a subclass?
@@ -492,15 +493,15 @@ impl PyDictRef {
492493
}
493494
}
494495

495-
impl<T> ItemProtocol<T> for PyDictRef
496+
impl<K> ItemProtocol<K> for PyDictRef
496497
where
497-
T: DictKey,
498+
K: DictKey,
498499
{
499-
fn get_item(&self, key: T, vm: &VirtualMachine) -> PyResult {
500+
fn get_item(&self, key: K, vm: &VirtualMachine) -> PyResult {
500501
self.as_object().get_item(key, vm)
501502
}
502503

503-
fn set_item(&self, key: T, value: PyObjectRef, vm: &VirtualMachine) -> PyResult {
504+
fn set_item(&self, key: K, value: PyObjectRef, vm: &VirtualMachine) -> PyResult {
504505
if self.lease_class().is(&vm.ctx.types.dict_type) {
505506
self.inner_setitem_fast(key, value, vm)
506507
.map(|_| vm.ctx.none())
@@ -510,7 +511,7 @@ where
510511
}
511512
}
512513

513-
fn del_item(&self, key: T, vm: &VirtualMachine) -> PyResult {
514+
fn del_item(&self, key: K, vm: &VirtualMachine) -> PyResult {
514515
if self.lease_class().is(&vm.ctx.types.dict_type) {
515516
self.entries.delete(vm, key).map(|_| vm.ctx.none())
516517
} else {

vm/src/obj/objframe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ impl FrameRef {
4646

4747
#[pyproperty]
4848
fn f_locals(self) -> PyDictRef {
49-
self.scope.get_locals()
49+
self.scope.get_locals().clone()
5050
}
5151

5252
#[pyproperty]

vm/src/pyobject.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::obj::objiter;
2727
use crate::obj::objlist::PyList;
2828
use crate::obj::objnamespace::PyNamespace;
2929
use crate::obj::objobject;
30-
use crate::obj::objset::PySet;
30+
use crate::obj::objset;
3131
use crate::obj::objsingletons::{PyNone, PyNoneRef, PyNotImplemented, PyNotImplementedRef};
3232
use crate::obj::objslice::PyEllipsis;
3333
use crate::obj::objstaticmethod::PyStaticMethod;
@@ -256,10 +256,10 @@ impl PyContext {
256256
PyObject::new(PyList::from(elements), self.types.list_type.clone(), None)
257257
}
258258

259-
pub fn new_set(&self) -> PyObjectRef {
259+
pub fn new_set(&self) -> objset::PySetRef {
260260
// Initialized empty, as calling __hash__ is required for adding each object to the set
261261
// which requires a VM context - this is done in the objset code itself.
262-
PyObject::new(PySet::default(), self.types.set_type.clone(), None)
262+
PyRef::new_ref(objset::PySet::default(), self.types.set_type.clone(), None)
263263
}
264264

265265
pub fn new_dict(&self) -> PyDictRef {

vm/src/scope.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ impl Scope {
4545
Scope::new(locals, globals, vm)
4646
}
4747

48-
pub fn get_locals(&self) -> PyDictRef {
48+
pub fn get_locals(&self) -> &PyDictRef {
4949
match self.locals.first() {
50-
Some(dict) => dict.clone(),
51-
None => self.globals.clone(),
50+
Some(dict) => dict,
51+
None => &self.globals,
5252
}
5353
}
5454

vm/src/vm.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ impl VirtualMachine {
700700
}
701701

702702
pub fn get_locals(&self) -> PyDictRef {
703-
self.current_scope().get_locals()
703+
self.current_scope().get_locals().clone()
704704
}
705705

706706
// Container of the virtual machine state:
@@ -783,7 +783,7 @@ impl VirtualMachine {
783783

784784
let (locals, globals) = if let Some(frame) = self.current_frame() {
785785
(
786-
frame.scope.get_locals().into_object(),
786+
frame.scope.get_locals().clone().into_object(),
787787
frame.scope.globals.clone().into_object(),
788788
)
789789
} else {

0 commit comments

Comments
 (0)