Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:127268 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id 23ABC1A00BC for ; Fri, 2 May 2025 08:14:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1746173563; bh=Au5mH912NrJqzWTSqVh/AJnCc7dEAqm2d8vlEJZop2I=; h=From:Date:Subject:To:From; b=VJtELFJghqVKPrbixK6LcH2wXt5N0Lz1vko1V89kyf+r/j7UwnebTxoNsExWtSlho 3qfwxTbObFnrK9ZWkSg8T19D5ntUlnreRh+wuuUYlgtmMjas78G3f8PbeWOLfpRDnV IqdWDZOb6SQp6WASl5BaT4gTQ03/omhP8G22H235hPzOjo/8O0qlhkY1Cnl3L5A0nw 3JwTaYD/LtD6lj69PtEDI5Af6F9sVeXqf+PE8yqvWd4tzA7/0ZVxOtffsbQ+ycyRNS 9Wzi+WUW/Pe2FmAmhRN339u83kLOgWZNln8oPuuckaAIrikdykR8q90buFKMqX4NTt vbT/WEgFgkymQ== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 5ED16180047 for ; Fri, 2 May 2025 08:12:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from mail-yw1-f175.google.com (mail-yw1-f175.google.com [209.85.128.175]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Fri, 2 May 2025 08:12:32 +0000 (UTC) Received: by mail-yw1-f175.google.com with SMTP id 00721157ae682-7080dd5fe92so15092107b3.3 for ; Fri, 02 May 2025 01:14:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1746173687; x=1746778487; darn=lists.php.net; h=content-transfer-encoding:to:subject:message-id:date:from :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=Au5mH912NrJqzWTSqVh/AJnCc7dEAqm2d8vlEJZop2I=; b=hoG4CgvZHVmrbre5e1T8saYg88xJRS+pM1+ElF8cQ2vo7wmMnunEWzetiDT3GmSz3J BPEj1utEKRN+9g4Kj2AFVqDtjVkW7gawBJ0TazJRP2r9sgZluKWzWD9m8w0KrgxwcJpP kSB6zlfdsnVJXZB7erjtvGXpep1lJUDLgvqJc+5SriQfJniJWDLBI31Dg4vKCiPwaUPF 5gwMzWBHfwvMtdqmF4N0/CEPSPhudCtppMQq6dtj6UMQew8hGDLeWhxTbYSilRuz9+2I +tI2lW+GKEuP4bc26nAzIN+AT7xy4ILX/jVb46MhqcJk6+zeSMAaYGLTDlJK/FhbFE9U MNbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1746173687; x=1746778487; h=content-transfer-encoding:to:subject:message-id:date:from :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Au5mH912NrJqzWTSqVh/AJnCc7dEAqm2d8vlEJZop2I=; b=NNhqhEStxdk6IVjneuB//5xUk7UeJDgZBkknsilveqd/pSJ9dhCfLT1mSza75CKnsw qd9Z8tuV+5rpeJAGc9R0vCJH6KNcqQmnCv84N9JTRAZk1yozH8AKOt0l1W99FkCWUilm Yu99fb3qjL9q1OZ6EGBDBFsQsyOb6hH5lYp/k6yB0x7mXvzATKXn/B0DSnIqbO7M5hDO 715aSHMk7hj577GAAjSLqcbDzApfqu4SraPDs2OChVVzxOS5tVHw71LYZkYCj+VZIgyI BhAU0B3sBKoe2berFBKQ9o4tzkK6ZIVkwNkgMp64P9tksNV0rb1nrfzG239lLDrwdhjE amqg== X-Gm-Message-State: AOJu0YzfMpT45Kbxo0hx1ashIufNwtb7t4FG79j6pGmB/Dcfmc60PDPN d2ihG43G6xMpKMGq6p602eDCcTjnhns+0HFMIWh/+kvEMIxwO0+X7pnOD3opzybqT1ceUs3qWzK cbDZn3c5rYLAQR+yEpFHAa72083Mn58ppOG8= X-Gm-Gg: ASbGncvuPSlDvz5QqmnBDKkzKsA3qSep0Bkq5akWi4wUVsflXlwoagdI3PSDLR/SZIM 25ZFGbl/HLkvDSGyAPdofm5Ct8Ewa/Dki9c318LAFHukGP7lcHKdCICYImI+Z9HMt3ffPP2shvk XvcxYLOj8FEtK+hbqo/e/32A== X-Google-Smtp-Source: AGHT+IFSFfjckjbv/Bf5AElu6XtHeTOwQ4qeF/R5Z++twyADRujltNmz9VKWFrUztCpbpkq/AFh5UdDow412zZKTlp8= X-Received: by 2002:a05:690c:64c4:b0:708:4f42:c2f6 with SMTP id 00721157ae682-708ced50a6cmr34096067b3.16.1746173686812; Fri, 02 May 2025 01:14:46 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Date: Fri, 2 May 2025 11:14:37 +0300 X-Gm-Features: ATxdqUG819mLeN-MCRErWKv2cRqCtjCjjmD9OB5vf7ROkqeD059Si5TQ6iJYWm4 Message-ID: Subject: [PHP-DEV] Deferred backtrace generation algorithm. To: php internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable From: edmond.ht@gmail.com (Edmond Dantes) Good day, everyone. In the neighboring thread Concept: Lightweight error channels, the topic of exception performance was discussed. The main issue is the immediate backtrace generation in the constructor, which can cause up to a 50% performance loss compared to return (as I understood from the discussion =E2=80=94 I may be mistaken). I have a small idea on how to improve the situation in cases where exceptions are caught and a backtrace isn't needed. Let=E2=80=99s assume we delay backtrace generation. In PHP, you can=E2=80= =99t just keep a reference to a stack frame, since it may be destroyed. You could copy it, of course (which is relatively inexpensive compared to generating the full backtrace). Based on that, there are two possible implementations: * Generate the backtrace at the moment the stack is freed * Clone the stack frame when the stack is freed (this is roughly what happens in Python) This would require changes to the functions `zend_vm_stack_free_extra_args_ex` and `zend_vm_stack_free_extra_args`. These functions could be used to either clone the stack frame or generate the full/partial backtrace at the right moment. The information about whether something is referencing a stack frame could be stored in a separate structure in `EG`, so there would be no need to modify `zend_execute_data`. Any code referencing the frame would, of course, need to correctly decrement the reference counter. For example, when an exception is created, it increments the reference count on the current call frame, which guarantees that the frame stays available until either the exception is destroyed or the backtrace is generated. Nuances: * It=E2=80=99s more efficient to copy only the parts of the stack frame nee= ded for the backtrace, not the entire frame. This also applies to parameter slots =E2=80=94 they should be converted immediately if the DEBUG_BACKTRACE_IGNORE_ARGS flag is not set. * When cloning the stack frame, the reference to the previous frame should automatically be incremented. At first glance, this algorithm doesn=E2=80=99t break backward compatibilit= y in any way and spreads out memory/CPU costs. Even if multiple exceptions are created within a function but no backtrace is generated, overall memory usage decreases, since Zend only retains the data structures currently needed, rather than duplicating them in each backtrace. Cloned call frames exist only once and can be shared across multiple except= ions. **What are the benefits?** * The cost of throwing an exception that is caught and not used at the top level is nearly equivalent to a return operation. * Lower memory usage when no backtrace is generated. * It becomes possible to reuse a single backtrace generation for multiple exceptions that share common frames (needs further consideration). **Drawbacks:** * Exiting a PHP function consumes CPU to copy ~100 bytes of memory. * Increased code complexity in the exception/stack frame modules. These conclusions were made mentally without writing actual code. But perhaps someone will have something to add =E2=80=94 either in favor or= against. --- Ed.