From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-Status: No, score=-3.8 required=3.0 tests=AWL,BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from neon.ruby-lang.org (neon.ruby-lang.org [221.186.184.75]) by dcvr.yhbt.net (Postfix) with ESMTP id 6FDF31F4B4 for ; Thu, 22 Oct 2020 00:53:05 +0000 (UTC) Received: from neon.ruby-lang.org (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id AB615120B2F; Thu, 22 Oct 2020 09:52:24 +0900 (JST) Received: from xtrwkhkc.outbound-mail.sendgrid.net (xtrwkhkc.outbound-mail.sendgrid.net [167.89.16.28]) by neon.ruby-lang.org (Postfix) with ESMTPS id D831C120B2E for ; Thu, 22 Oct 2020 09:52:22 +0900 (JST) Received: by filterdrecv-p3iad2-786ff7f994-tl497 with SMTP id filterdrecv-p3iad2-786ff7f994-tl497-17-5F90D7EA-9 2020-10-22 00:52:58.201784303 +0000 UTC m=+23068.581433269 Received: from herokuapp.com (unknown) by ismtpd0092p1iad2.sendgrid.net (SG) with ESMTP id HyDSBfWASYmaWOSiY0y7_w for ; Thu, 22 Oct 2020 00:52:58.182 +0000 (UTC) Date: Thu, 22 Oct 2020 00:52:58 +0000 (UTC) From: ko1@atdot.net Message-ID: References: Mime-Version: 1.0 X-Redmine-MailingListIntegration-Message-Ids: 76355 X-Redmine-Project: ruby-master X-Redmine-Issue-Tracker: Feature X-Redmine-Issue-Id: 17273 X-Redmine-Issue-Author: ko1 X-Redmine-Sender: ko1 X-Mailer: Redmine X-Redmine-Host: bugs.ruby-lang.org X-Redmine-Site: Ruby Issue Tracking System X-Auto-Response-Suppress: All Auto-Submitted: auto-generated X-SG-EID: =?us-ascii?Q?fVTMYOBjtdvXNcWwrscBhLsHItUXVK5L4mtnq0mdcRf=2F=2FkkIqGOqgtGZFHCypU?= =?us-ascii?Q?iuEDfpgjX90jx6g4WyW33UY0HMMemxftJJGDQ5d?= =?us-ascii?Q?P0MnIlxUX9WGqPyAd9+nrknDaZH+jgyx0m5XNXB?= =?us-ascii?Q?n6p2aiPKnZgC9=2F5xIWdQjWgSjQd68eRMblqjbZT?= =?us-ascii?Q?DJV2pP8L1MiRHEJyNaSw9riQDy0bjR9DPFQ=3D=3D?= To: ruby-core@ruby-lang.org X-Entity-ID: b/2+PoftWZ6GuOu3b0IycA== X-ML-Name: ruby-core X-Mail-Count: 100485 Subject: [ruby-core:100485] [Ruby master Feature#17273] shareable_constant_value pragma X-BeenThere: ruby-core@ruby-lang.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: Ruby developers List-Id: Ruby developers List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ruby-core-bounces@ruby-lang.org Sender: "ruby-core" Issue #17273 has been updated by ko1 (Koichi Sasada). Eregon (Benoit Daloze) wrote in #note-5: > If there are that many constants, I think there is a high chance the value is an immediate or a String, then there is no need. We can eliminate calling by compile time, in future. ---------------------------------------- Feature #17273: shareable_constant_value pragma https://bugs.ruby-lang.org/issues/17273#change-88105 * Author: ko1 (Koichi Sasada) * Status: Open * Priority: Normal ---------------------------------------- This proposal is to introduce `# shareable_constant_value: true` pragma to make constant values shareable objects. With this pragma, you don't need to add `freeze` to access from non-main ractors. ```ruby # shareable_constant_value: true A = [1, [2, [3, 4]]] H = {a: "a"} Ractor.new do p A p H end.take ``` ## Background Now, we can not access constants which contains a unshareable object from the non-main Ractor. ```ruby A = [1, [2, [3, 4]]] H = {a: "a"} Ractor.new do p A #=> can not access non-sharable objects in constant Object::A by non-main Ractor. (NameError) p H end.take ``` If we know we don't modify `A` and `H` is frozen object, we can freeze them, and other ractors can access them. ```ruby A = [1, [2, [3, 4].freeze].freeze].freeze H = {a: "a".freeze}.freeze Ractor.new do p A #=> [1, [2, [3, 4]]] p H #=> {:a=>"a"} end.take ``` Adding nesting data structure, we need many `.freeze` method. Recently, I added `Ractor.make_shareable(obj)` makes `obj` shareable with freezing objects deeply (see [Feature #17274]). We only need to introduce this method for each constant. ```ruby A = Ractor.make_shareable( [1, [2, [3, 4]]] ) H = Ractor.make_shareable( {a: "a"} ) Ractor.new do p A #=> [1, [2, [3, 4]]] p H #=> {:a=>"a"} end.take ``` However, if we have 100 constants, it is troublesome. ## Proposal With `# shareable_constant_value: true`, you can specify all constants are shareable. ```ruby # shareable_constant_value: true A = [1, [2, [3, 4]]] # compiled with: A = Ractor.make_shareable( [1, [2, [3, 4]]] ) H = {a: "a"} # compiled with: H = Ractor.make_shareable( {a: "a"} ) Ractor.new do p A p H end.take ``` (Strictly speaking, don't call `Ractor.make_shareable`, but apply same effect. This means rewriting `Ractor.make_shareable` doesn't affect this behavior) You can specify `# shareable_constant_value: false` in the middle of the place. ```ruby # shareable_constant_value: true S1 = 'str' # p S1.frozen? #=> true # shareable_constant_value: false S2 = 'str' # p S2.frozen? #=> false ``` The effect of this pragma is closed to the scope. ```ruby class C # shareable_constant_value: true A = 'str' p A.frozen? #=> true 1.times do # shareable_constant_value: false B = 'str' p B.frozen? #=> false end end X = 'str' p X.frozen? #=> false ``` `Ractor.make_shareable(obj)` doesn't affect anything to shareable objects. ```ruby # shareable_constant_value: true class C; end D = C p D.frozen? #=> false ``` Some objects can not become shareable objects, so it raises an exception: ```ruby # shareable_constant_value: true T = Thread.new{} #=> `make_shareable': can not make shareable object for # (Ractor::Error) ``` ## Implementation https://github.com/ruby/ruby/pull/3681/files -- https://bugs.ruby-lang.org/