Skip to content

Commit

Permalink
pydict_setitem!!(), setitem_knownhash
Browse files Browse the repository at this point in the history
  • Loading branch information
ijl committed Oct 29, 2024
1 parent bb49c67 commit e9432d3
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 21 deletions.
9 changes: 1 addition & 8 deletions src/deserialize/backend/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,7 @@ impl<'de> Visitor<'de> for JsonValue {
while let Some(key) = map.next_key::<Cow<str>>()? {
let pykey = get_unicode_key(&key);
let pyval = map.next_value_seed(self)?;
let _ = unsafe {
pyo3_ffi::_PyDict_SetItem_KnownHash(
dict_ptr,
pykey,
pyval.as_ptr(),
str_hash!(pykey),
)
};
let _ = pydict_setitem!(dict_ptr, pykey, pyval.as_ptr());
reverse_pydict_incref!(pykey);
reverse_pydict_incref!(pyval.as_ptr());
}
Expand Down
12 changes: 3 additions & 9 deletions src/deserialize/backend/yyjson.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,12 +230,6 @@ fn populate_yy_array(list: *mut pyo3_ffi::PyObject, elem: *mut yyjson_val) {
}
}

macro_rules! add_to_dict {
($dict:expr, $pykey:expr, $pyval:expr) => {
unsafe { pyo3_ffi::_PyDict_SetItem_KnownHash($dict, $pykey, $pyval, str_hash!($pykey)) }
};
}

#[inline(never)]
fn populate_yy_object(dict: *mut pyo3_ffi::PyObject, elem: *mut yyjson_val) {
unsafe {
Expand All @@ -257,15 +251,15 @@ fn populate_yy_object(dict: *mut pyo3_ffi::PyObject, elem: *mut yyjson_val) {
next_val = next_key.add(1);
if is_yyjson_tag!(val, TAG_ARRAY) {
let pyval = ffi!(PyList_New(unsafe_yyjson_get_len(val) as isize));
add_to_dict!(dict, pykey, pyval);
pydict_setitem!(dict, pykey, pyval.as_ptr());
reverse_pydict_incref!(pykey);
reverse_pydict_incref!(pyval);
if unsafe_yyjson_get_len(val) > 0 {
populate_yy_array(pyval, val);
}
} else {
let pyval = ffi!(_PyDict_NewPresized(unsafe_yyjson_get_len(val) as isize));
add_to_dict!(dict, pykey, pyval);
pydict_setitem!(dict, pykey, pyval.as_ptr());
reverse_pydict_incref!(pykey);
reverse_pydict_incref!(pyval);
if unsafe_yyjson_get_len(val) > 0 {
Expand All @@ -286,7 +280,7 @@ fn populate_yy_object(dict: *mut pyo3_ffi::PyObject, elem: *mut yyjson_val) {
ElementType::Array => unreachable!(),
ElementType::Object => unreachable!(),
};
add_to_dict!(dict, pykey, pyval.as_ptr());
pydict_setitem!(dict, pykey, pyval.as_ptr());
reverse_pydict_incref!(pykey);
reverse_pydict_incref!(pyval.as_ptr());
}
Expand Down
1 change: 1 addition & 0 deletions src/deserialize/pyobject.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub fn get_unicode_key(key_str: &str) -> *mut pyo3_ffi::PyObject {
|| hash,
|| {
let pyob = unicode_from_str(key_str);
#[cfg(feature = "setitem_knownhash")]
hash_str(pyob);
CachedKey::new(pyob)
},
Expand Down
8 changes: 4 additions & 4 deletions src/str/ffi.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
// SPDX-License-Identifier: (Apache-2.0 OR MIT)

use core::ffi::c_void;
use pyo3_ffi::*;

// see unicodeobject.h for documentation

#[cfg(feature = "setitem_knownhash")]
#[inline]
pub fn hash_str(op: *mut PyObject) -> Py_hash_t {
unsafe {
let data_ptr: *mut c_void = if (*op.cast::<PyASCIIObject>()).compact() == 1
let data_ptr: *mut core::ffi::c_void = if (*op.cast::<PyASCIIObject>()).compact() == 1
&& (*op.cast::<PyASCIIObject>()).ascii() == 1
{
(op as *mut PyASCIIObject).offset(1) as *mut c_void
(op as *mut PyASCIIObject).offset(1) as *mut core::ffi::c_void
} else {
(op as *mut PyCompactUnicodeObject).offset(1) as *mut c_void
(op as *mut PyCompactUnicodeObject).offset(1) as *mut core::ffi::c_void
};
let num_bytes =
(*(op as *mut PyASCIIObject)).length * ((*(op as *mut PyASCIIObject)).kind()) as isize;
Expand Down
26 changes: 26 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,32 @@ macro_rules! pydict_next {
};
}

#[cfg(feature = "setitem_knownhash")]
macro_rules! pydict_setitem {
($dict:expr, $pykey:expr, $pyval:expr) => {
#[cfg(not(Py_3_14))]
unsafe {
pyo3_ffi::_PyDict_SetItem_KnownHash($dict, $pykey, $pyval, str_hash!($pykey))
}
#[cfg(Py_3_14)]
unsafe {
pyo3_ffi::_PyDict_SetItem_KnownHash_LockHeld(
$dict as *mut pyo3_ffi::PyDictObject,
$pykey,
$pyval,
str_hash!($pykey),
)
}
};
}

#[cfg(not(feature = "setitem_knownhash"))]
macro_rules! pydict_setitem {
($dict:expr, $pykey:expr, $pyval:expr) => {
unsafe { pyo3_ffi::PyDict_SetItem($dict, $pykey, $pyval) }
};
}

macro_rules! reserve_minimum {
($writer:expr) => {
$writer.reserve(64);
Expand Down

0 comments on commit e9432d3

Please sign in to comment.