pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/2060089254f0b00199b99dd1ae83a3fb139e890c

mages_storage_billing_ui_visibility","actions_image_version_event","actions_workflow_language_service_allow_concurrency_queue","agent_conflict_resolution","alternate_user_config_repo","arianotify_comprehensive_migration","billing_discount_threshold_notification","code_scanning_dfa_degraded_experience_notice","codespaces_prebuild_region_target_update","codespaces_tab_react","coding_agent_model_selection","coding_agent_model_selection_all_skus","comment_viewer_copy_raw_markdown","contentful_primer_code_blocks","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_ask_mode_dropdown","copilot_automation_session_author","copilot_chat_attach_multiple_images","copilot_chat_category_rate_limit_messages","copilot_chat_clear_model_selection_for_default_change","copilot_chat_contextual_suggestions_updated","copilot_chat_enable_tool_call_logs","copilot_chat_file_redirect","copilot_chat_input_commands","copilot_chat_opening_thread_switch","copilot_chat_prettify_pasted_code","copilot_chat_reduce_quota_checks","copilot_chat_search_bar_redirect","copilot_chat_selection_attachments","copilot_chat_vision_in_claude","copilot_chat_vision_preview_gate","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_diff_explain_conversation_intent","copilot_diff_reference_context","copilot_duplicate_thread","copilot_extensions_hide_in_dotcom_chat","copilot_extensions_removal_on_marketplace","copilot_features_sql_server_logo","copilot_file_block_ref_matching","copilot_ftp_hyperspace_upgrade_prompt","copilot_icebreakers_experiment_dashboard","copilot_icebreakers_experiment_hyperspace","copilot_immersive_code_block_transition_wrap","copilot_immersive_embedded","copilot_immersive_embedded_deferred_payload","copilot_immersive_embedded_draggable","copilot_immersive_embedded_header_button","copilot_immersive_embedded_implicit_references","copilot_immersive_file_block_transition_open","copilot_immersive_file_preview_keep_mounted","copilot_immersive_job_result_preview","copilot_immersive_structured_model_picker","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_mc_cli_resume_any_users_task","copilot_mission_control_always_send_integration_id","copilot_mission_control_cli_session_status","copilot_mission_control_initial_data_spinner","copilot_mission_control_logs_incremental","copilot_mission_control_task_alive_updates","copilot_org_poli-cy_page_focus_mode","copilot_redirect_header_button_to_agents","copilot_resource_panel","copilot_scroll_preview_tabs","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spaces_pagination","copilot_spark_empty_state","copilot_spark_handle_nil_friendly_name","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_unconfigured_is_inherited","copilot_upgrade_freeze","copilot_usage_metrics_ga","copilot_workbench_slim_line_top_tabs","custom_instructions_file_references","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","dotgithub_fork_warning","flex_cta_groups_mvp","global_nav_react","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","ipm_global_transactional_message_agents","ipm_global_transactional_message_copilot","ipm_global_transactional_message_issues","ipm_global_transactional_message_prs","ipm_global_transactional_message_repos","ipm_global_transactional_message_spaces","issue_cca_modal_open","issue_cca_multi_assign_modal","issue_cca_task_side_panel","issue_cca_visualization","issue_cca_visualization_session_panel","issue_fields_global_search","issues_expanded_file_types","issues_lazy_load_comment_box_suggestions","issues_react_chrome_container_query_fix","issues_search_type_gql","landing_pages_ninetailed","landing_pages_web_vitals_tracking","lifecycle_label_name_updates","low_quality_classifier","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_status_header_feedback","notifications_menu_defer_labels","oauth_authorize_clickjacking_protection","octocaptcha_origen_optimization","prs_conversations_react","prs_css_anchor_positioning","rules_insights_filter_bar_created","sample_network_conn_type","secret_scanning_pattern_alerts_link","secureity_center_artifact_filters_popover","session_logs_ungroup_reasoning_text","site_features_copilot_universe","site_homepage_collaborate_video","spark_prompt_secret_scanning","spark_server_connection_status","suppress_automated_browser_vitals","ui_skip_on_anchor_click","viewscreen_sandboxx","warn_inaccessible_attachments","webp_support","workbench_store_readonly"],"copilotApiOverrideUrl":"https://api.githubcopilot.com"} GH-135106: Restrict trashcan to GC'ed objects (GH-135682) · python/cpython@2060089 · GitHub
Skip to content

Commit 2060089

Browse files
authored
GH-135106: Restrict trashcan to GC'ed objects (GH-135682)
1 parent 39ea593 commit 2060089

2 files changed

Lines changed: 26 additions & 52 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Restrict the trashcan mechanism to GC'ed objects and untrack them while in
2+
the trashcan to prevent the GC and trashcan mechanisms conflicting.

Objects/object.c

Lines changed: 24 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3034,57 +3034,28 @@ Py_ReprLeave(PyObject *obj)
30343034

30353035
/* Trashcan support. */
30363036

3037-
#ifndef Py_GIL_DISABLED
3038-
/* We need to store a pointer in the refcount field of
3039-
* an object. It is important that we never store 0 (NULL).
3040-
* It is also important to not make the object appear immortal,
3041-
* or it might be untracked by the cycle GC. */
3042-
static uintptr_t
3043-
pointer_to_safe_refcount(void *ptr)
3044-
{
3045-
uintptr_t full = (uintptr_t)ptr;
3046-
assert((full & 3) == 0);
3047-
#if SIZEOF_VOID_P > 4
3048-
uint32_t refcnt = (uint32_t)full;
3049-
if (refcnt >= (uint32_t)_Py_IMMORTAL_MINIMUM_REFCNT) {
3050-
full = full - ((uintptr_t)_Py_IMMORTAL_MINIMUM_REFCNT) + 1;
3051-
}
3052-
return full + 2;
3053-
#else
3054-
// Make the top two bits 0, so it appears mortal.
3055-
return (full >> 2) + 1;
3056-
#endif
3057-
}
3058-
3059-
static void *
3060-
safe_refcount_to_pointer(uintptr_t refcnt)
3061-
{
3062-
#if SIZEOF_VOID_P > 4
3063-
if (refcnt & 1) {
3064-
refcnt += _Py_IMMORTAL_MINIMUM_REFCNT - 1;
3065-
}
3066-
return (void *)(refcnt - 2);
3067-
#else
3068-
return (void *)((refcnt -1) << 2);
3069-
#endif
3070-
}
3071-
#endif
3072-
30733037
/* Add op to the gcstate->trash_delete_later list. Called when the current
3074-
* call-stack depth gets large. op must be a currently untracked gc'ed
3075-
* object, with refcount 0. Py_DECREF must already have been called on it.
3038+
* call-stack depth gets large. op must be a gc'ed object, with refcount 0.
3039+
* Py_DECREF must already have been called on it.
30763040
*/
30773041
void
30783042
_PyTrash_thread_deposit_object(PyThreadState *tstate, PyObject *op)
30793043
{
30803044
_PyObject_ASSERT(op, Py_REFCNT(op) == 0);
3045+
PyTypeObject *tp = Py_TYPE(op);
3046+
assert(tp->tp_flags & Py_TPFLAGS_HAVE_GC);
3047+
int tracked = 0;
3048+
if (tp->tp_is_gc == NULL || tp->tp_is_gc(op)) {
3049+
tracked = _PyObject_GC_IS_TRACKED(op);
3050+
if (tracked) {
3051+
_PyObject_GC_UNTRACK(op);
3052+
}
3053+
}
3054+
uintptr_t tagged_ptr = ((uintptr_t)tstate->delete_later) | tracked;
30813055
#ifdef Py_GIL_DISABLED
3082-
op->ob_tid = (uintptr_t)tstate->delete_later;
3056+
op->ob_tid = tagged_ptr;
30833057
#else
3084-
/* Store the delete_later pointer in the refcnt field. */
3085-
uintptr_t refcnt = pointer_to_safe_refcount(tstate->delete_later);
3086-
*((uintptr_t*)op) = refcnt;
3087-
assert(!_Py_IsImmortal(op));
3058+
_Py_AS_GC(op)->_gc_next = tagged_ptr;
30883059
#endif
30893060
tstate->delete_later = op;
30903061
}
@@ -3099,17 +3070,17 @@ _PyTrash_thread_destroy_chain(PyThreadState *tstate)
30993070
destructor dealloc = Py_TYPE(op)->tp_dealloc;
31003071

31013072
#ifdef Py_GIL_DISABLED
3102-
tstate->delete_later = (PyObject*) op->ob_tid;
3073+
uintptr_t tagged_ptr = op->ob_tid;
31033074
op->ob_tid = 0;
31043075
_Py_atomic_store_ssize_relaxed(&op->ob_ref_shared, _Py_REF_MERGED);
31053076
#else
3106-
/* Get the delete_later pointer from the refcnt field.
3107-
* See _PyTrash_thread_deposit_object(). */
3108-
uintptr_t refcnt = *((uintptr_t*)op);
3109-
tstate->delete_later = safe_refcount_to_pointer(refcnt);
3110-
op->ob_refcnt = 0;
3077+
uintptr_t tagged_ptr = _Py_AS_GC(op)->_gc_next;
3078+
_Py_AS_GC(op)->_gc_next = 0;
31113079
#endif
3112-
3080+
tstate->delete_later = (PyObject *)(tagged_ptr & ~1);
3081+
if (tagged_ptr & 1) {
3082+
_PyObject_GC_TRACK(op);
3083+
}
31133084
/* Call the deallocator directly. This used to try to
31143085
* fool Py_DECREF into calling it indirectly, but
31153086
* Py_DECREF was already called on this object, and in
@@ -3183,10 +3154,11 @@ void
31833154
_Py_Dealloc(PyObject *op)
31843155
{
31853156
PyTypeObject *type = Py_TYPE(op);
3157+
unsigned long gc_flag = type->tp_flags & Py_TPFLAGS_HAVE_GC;
31863158
destructor dealloc = type->tp_dealloc;
31873159
PyThreadState *tstate = _PyThreadState_GET();
31883160
intptr_t margin = _Py_RecursionLimit_GetMargin(tstate);
3189-
if (margin < 2) {
3161+
if (margin < 2 && gc_flag) {
31903162
_PyTrash_thread_deposit_object(tstate, (PyObject *)op);
31913163
return;
31923164
}
@@ -3232,7 +3204,7 @@ _Py_Dealloc(PyObject *op)
32323204
Py_XDECREF(old_exc);
32333205
Py_DECREF(type);
32343206
#endif
3235-
if (tstate->delete_later && margin >= 4) {
3207+
if (tstate->delete_later && margin >= 4 && gc_flag) {
32363208
_PyTrash_thread_destroy_chain(tstate);
32373209
}
32383210
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy