summaryrefslogtreecommitdiff
path: root/runtime/intern_table.h
AgeCommit message (Collapse)Author
2024-06-20Move some classes from `runtime/` to `dex2oat/`. Vladimir Marko
Move the transactional interpreter, `AotClassLinker`, `Transaction` and `SdkChecker`. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Change-Id: If001e06711ee345ce5b937ed764e66b26a0abcd6
2024-01-24Add visibility attributes in runtime/i* Dmitrii Ishcheikin
Bug: 260881207 Test: presubmit Test: abtd app_compat_drm Test: abtd app_compat_top_100 Test: abtd app_compat_banking Change-Id: I017173510501982607b7688b55ee27a0389abb3d
2023-10-17Revert^2 "Update class-table and intern-table concurrently with uffd GC" Lokesh Gidra
This reverts commit 9faffd5c4e062ca45bd6f29a3b6d1b276e6c9839. Reason for revert: Reland after fixing null-pointer dereference Bug: 160737021 Test: art/testrunner/testrunner.py Change-Id: I80d3eda827ea805efc5a0e0eb0b80a9d8ceb9dd5
2023-10-17Revert "Update class-table and intern-table concurrently with uffd GC" Lokesh Gidra
This reverts commit 97a6f7cd191cde0abaaf6323ae2f67d8e42a1236. Reason for revert: LUCI failure in libcore test Change-Id: I381b261ae0f67103bf1d096d8f64c84ba3f3e19c
2023-10-17Update class-table and intern-table concurrently with uffd GC Lokesh Gidra
Bug: 160737021 Test: art/testrunner/testrunner.py Change-Id: I4413ead05947f3f865116ae8dc7d67d860106b37
2022-04-05Do not repeatedly search frozen strong intern tables. Vladimir Marko
Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Bug: 181943478 Bug: 223545499 Change-Id: Idf18993a5c51e88fcc7b62a11e46332630886b44
2022-04-05String hashing cleanup in `InternTable`. Vladimir Marko
Keep the hash code in `String` as `int32_t` but work with unsigned hash in `InternTable` and add `static_cast<>`s where needed. Make sure that the hash code is stored in the `String` before inserting it in the `InternTable` and avoid the check whether it's calculated in the hash function. Add `DCHECK()`s to verify that the stored hash code is correct. Pass the hash code between `InternTable` functions to avoid repeatedly retrieving it from the string if the compiler is unable to prove that the memory location did not change. Remove unnecessary `*FromTransaction` helper functions that were just doing a `DCHECK()` and then forwarding to other functions. Update `Transaction` to do that DCHECK() and call the needed functions directly. Make an explicit decision to calculate hash code for all image strings, including those that are not interned. We previously calculated hash code for all app image strings by accident while collecting interned string references. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Bug: 181943478 Change-Id: I7cec91e797fdb98ae52f9666620d7b311d465422
2022-03-21Use correct min/max load factor in intern/class table. Vladimir Marko
Propagate the min/max load factor that was initially set based on low memory mode flag to new internal sets. And clean up some dead code related to image writing. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Change-Id: Id13c8a4833e93458a3f5eed22dc69431311211b7
2022-02-24Avoid Modified-UTF8 processing for ASCII strings. Vladimir Marko
Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Bug: 181943478 Change-Id: I9926a0d3e0160aa56ba7a02922388bb3007aaccb
2022-02-17Avoid unnecessary read barriers in `ImageWriter`. Vladimir Marko
Also avoid visiting native roots during the same stages, namely layout and writing (including copy-and-fixup). Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Bug: 181943478 Change-Id: I0d62d67556109dbcbd8a04fd0e8408733dacce33
2022-01-26Revert^2 "Reduce pauses for weak reference access" Hans Boehm
This reverts commit 07cbc5ba4f117ea74faecffe14ffc0ce8aa7ee0e. PS1 is identical to aosp/1933038 . PS2 applies a small fix for the CMS build. Original commit message: Remove the "preserve references" machinery. Instead let the reference processor inform GetReferent about its state, so that it can leverage knowledge about whether reachable memory has in fact been completely marked. Restructure the ReferenceProcessor interface by adding Setup to ensure that ReferenceProcessor fields are properly set up before we disable the normal fast path through GetReferent. For the CC collector, forward essentially all SoftReferences as part of normal marking, so we don't stall weak reference access for those. Note briefly in the log if we encounter References that are only reachable from finalizers. SS and MS collectors are only minimally updated to keep them working. We now block in GetReferent only for the hopefully very brief period of marking objects that were initially missed as a result of a mutator collector race. This should hopefully eliminate multi-millisecond delays here. For 2043-reference-pauses from aosp/1952438, it reduces blocking from over 100 msecs to under 1 on host. This is mostly due to the better SoftReference treatment; 100 msec pauses in GetReferent() were never near-typical. We iteratively mark through SoftReferences now. Previously we could mistakenly clear SoftReferences discovered while marking from the top level ones. (Lokesh pointed this out.) To make this work, we change ForwardSoftReferences to actually remove References from the queue, as the comment always said it did. This also somewhat prepares us for a much less complete solution for pauses to access WeakGlobalRefs or other "system weaks". This fixes a memory ordering issue for the per-thread weak reference access flags used with the CC collector. I think the issue is still there for the CMS collector. That requires further discussion. Bug: 190867430 Bug: 189738006 Bug: 211784084 Test: Build and boot aosp & Treehugger; aosp/195243 Change-Id: I9aa38da6c87555302243bd6c7d460747277ba8e7
2022-01-26Revert "Reduce pauses for weak reference access" Hans Boehm
This reverts commit 0ab5b6d2afbdd71a18f8fb9b1fcf39e54cfd55a5. Reason for revert: Breaks CMS builds Change-Id: Ib3dfcc90ac5b7259c7f718a0373b48acc2ba10b2
2022-01-26Reduce pauses for weak reference access Hans Boehm
Remove the "preserve references" machinery. Instead let the reference processor inform GetReferent about its state, so that it can leverage knowledge about whether reachable memory has in fact been completely marked. Restructure the ReferenceProcessor interface by adding Setup to ensure that ReferenceProcessor fields are properly set up before we disable the normal fast path through GetReferent. For the CC collector, forward essentially all SoftReferences as part of normal marking, so we don't stall weak reference access for those. Note briefly in the log if we encounter References that are only reachable from finalizers. SS and MS collectors are only minimally updated to keep them working. We now block in GetReferent only for the hopefully very brief period of marking objects that were initially missed as a result of a mutator collector race. This should hopefully eliminate multi-millisecond delays here. For 2043-reference-pauses from aosp/1952438, it reduces blocking from over 100 msecs to under 1 on host. This is mostly due to the better SoftReference treatment; 100 msec pauses in GetReferent() were never near-typical. We iteratively mark through SoftReferences now. Previously we could mistakenly clear SoftReferences discovered while marking from the top level ones. (Lokesh pointed this out.) To make this work, we change ForwardSoftReferences to actually remove References from the queue, as the comment always said it did. This also somewhat prepares us for a much less complete solution for pauses to access WeakGlobalRefs or other "system weaks". This fixes a memory ordering issue for the per-thread weak reference access flags used with the CC collector. I think the issue is still there for the CMS collector. That requires further discussion. Bug: 190867430 Bug: 189738006 Bug: 211784084 Test: Build and boot aosp & Treehugger; aosp/195243 Change-Id: I02f12ac481db4c4e400d253662a7a126318d4bec
2021-02-08Avoid an unnecessary ComputeModifiedUtf8Hash(). Vladimir Marko
The DescriptorHashPair already has the hash as the member `second`, so avoid recalculating it in release mode. Also split "HashEquals" classes into separate "Hash" and "Equals" classes to disambiguate their operators in traces. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Bug: 175869411 Change-Id: I87cbe613778c7d310ba5c2bf437729244780472c
2021-01-28Rewrite intern table construction in ImageWriter. Vladimir Marko
Make sure that intern tables in images are at maximum load factor (full) and make that maximum load factor independent of runtime parameters. As we pre-allocate an intern table buffer of the right size in ImageWriter, we also avoid unnecessary resizing of the temporary intern table. Instead of using InternTable::LookupStrong() for intern lookup, access the internal non-boot image intern table directly. This avoids unnecessary lookups in boot image intern tables and the intern table lock is locked only once instead of locking for each StringId in input dex files. Remove obsolete comment related to patchoat relocations. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Test: boots. Bug: 175869411 Change-Id: Ie74e1ac1b1b1d25add74edd38b7e1d70b6654ee3
2020-03-31Deduplicate interned image strings. Vladimir Marko
Also fix a bug in relocation; even for -Xnorelocate we need to relocate second and later extension if it's not compiled against all previous boot image components. Also clean up InternTable includes. Test: New tests in image_space_test. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Test: aosp_taimen-userdebug boots. Bug: 152037801 Change-Id: Ie6ae70721f4ffb48950bd248ffa123dee460bcd7
2019-06-27GC-independent image layout. Vladimir Marko
Make sure we visit objects in a defined order, independent of their order in the heap. The new order depends only on dex file contents and contents of initialized classes, thus any non-determinism would have to be contributed by the class initialization itself rather than GC. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Test: aosp_taimen-userdebug boots. Test: run-gtests.sh Test: testrunner.py --target --optimizing Bug: 26687569 Change-Id: I62521322289a22eb13faae526ba2c3589e6ab381
2019-06-12Do not force-intern Strings in images. Vladimir Marko
Interning all image Strings breaks the reference equality semantics. See android.net.Uri.NOT_CACHED for an example where it goes against the intent of the Java code. Instead, only put interned strings (weakly and strongly) to the image intern tables. Since image interns are referenced as long as the image is memory, we can promote weak interns to strong interns. Doing this before the image layout helps ImageWriter::CalculateNewObjectOffsets() which would not have previously found weak interns. Added a regression test that relies on better initialization of app image classes, so it shall be "active" only after an improvement in that area. (This can be checked by commenting out the NoClinitInDependency() check in CompilerDriver's InitializeClassVisitor::TryInitializeClass().) Bug: 134746125 Test: 176-app-image-string Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Test: aosp_taimen-userdebug boots. Test: run-gtests.sh Test: testrunner.py --target --optimizing Change-Id: I51fa1edf953c9060c41f39812f3ba27f12b02801
2018-11-02Smarter set intersection between app image and non boot image strings Mathieu Chartier
If there are fewer non boot image strings in the runtime, iterate over those strings instead of the set being newly added. On AOSP, nonBootImageInternStrings is around 500. Test: test-art-host Bug: 116059983 Change-Id: I76b49f2090971cf593ba487889b35dfc1fa8cf13
2018-11-01Track what intern tables are from boot images Mathieu Chartier
Goal: Use this to make it faster to do collision checks between app image intern tables against the non boot image intern tables. Bug: 116059983 Test: test-art-host Change-Id: I7a2305167335da5b6685822894f7985970e99053
2018-10-31Hold intern table lock for AddImageStringsToTable Mathieu Chartier
Fixes a correctness issue where another thread adding an intern string after the visitor could cause duplicate strings. Reduces how often the intern table lock is acquired, probably improving performance. Bug: 116059983 Test: test-art-host Change-Id: I5ba6ca3ba7535de6d4ad5cb46750bd23a6e9aadc
2018-10-15Add extra handling for loading intern tables Mathieu Chartier
Add an extra pass to fix up the app image intern table using a visitor. This visitor records if there are any image conflicts and avoids the image fixup phase if there are none. Added logic to bulk add the image intern table to the boot image. Will add optimizations later. Bug: 116059983 Test: test-art-host Change-Id: I50a6fdaf9c9a049a3d120e88d63fe7da8c9a298c
2018-09-28Revert^2 "Load boot image at a random address." Vladimir Marko
This reverts commit f3d077373536c54824e4449759dff2f18369eab3. Fixed Heap constructor to reserve extra space for GSS. Change-Id: I6a65be35f4aa183304db5491da4a4810d8e3b266 Test: m test-art-host-gtest Test: testrunner.py --host --optimizing --relocate --no-relocate Test: Pixel 2 XL boots. Test: m test-art-target-gtest Test: testrunner.py --target --optimizing --relocate --no-relocate Test: art/test/testrunner/run_build_test_target.py -j48 art-gtest-gss-gc-tlab Bug: 77856493
2018-09-27Revert "Load boot image at a random address." Vladimir Marko
This reverts commit 5ad79d85d77a42456728897ac3e2e7d4530e618e. Reason for revert: Breaks GSS garbage collection config. Bug: 77856493 Change-Id: Ifa39966ac2470154f8ba093de4804689d545219b
2018-09-26Load boot image at a random address. Vladimir Marko
And perform in-place fixup of references and pointers. This dirties all the boot image memory loaded by zygote, so there shall be no "shared clean" boot image pages anymore, these shall change to "shared dirty". However, as we're using a profile-based boot image, these pages are presumably used often enough and unlikely to be paged out anyway. The in-place fixup takes around 60-120ms when starting the zygote on aosp_taimen-userdebug. However, an experiment with MAP_POPULATE pushes the raw fixup down to around 12-15ms. If we used compressed images, this would be the actual time for fixup as the data would be already present in memory. If we keep using uncompressed images, we shall need to tune the loading with MAP_POPULATE or MADV_WILLNEED. The -Xrelocate/-Xno-relocate option is re-interpreted from "use patchoat if needed" to "relocate the boot image in memory if possible". We do not allow relocation for the AOT compilation to speed up dex2oat execution and help producing deterministic output. The patchoat tool shall be removed in a follow-up CL. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing --relocate --no-relocate Test: Pixel 2 XL boots. Test: m test-art-target-gtest Test: testrunner.py --target --optimizing --relocate --no-relocate Bug: 77856493 Change-Id: I2db1fabefb5d4b85c798cd51e04c78cb232bff4a
2018-07-19Move .art.rel data to a section in .art, part 1. Vladimir Marko
Refactor the code so that we can collect all relocation offsets while writing the image. Test: Manually verify that the aosp_taimen-userdebug boot image is identical before and after this change; using WIP follow-up code, check that we record the same locations as the patchoat-generated .rel files. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Bug: 77856493 Change-Id: Id8c78e417e77e859a82a680504253f41e84560d6
2018-03-09Merge "Retrieve String/Class references from .data.bimg.rel.ro." Vladimir Marko
2018-03-08Retrieve String/Class references from .data.bimg.rel.ro. Vladimir Marko
For PIC AOT-compiled app, use the .data.bimg.rel.ro to load the boot image String/Class references instead of using the mmapped boot image ClassTable and InternTable. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing --pictest --npictest Test: Pixel 2 XL boots. Test: testrunner.py --target --optimizing --pictest --npictest Bug: 71526895 Change-Id: Id5703229777aecb589a933a41f92e44d3ec02a3d
2018-03-05Move most of runtime/base to libartbase/base David Sehr
Enforce the layering that code in runtime/base should not depend on runtime by separating it into libartbase. Some of the code in runtime/base depends on the Runtime class, so it cannot be moved yet. Also, some of the tests depend on CommonRuntimeTest, which itself needs to be factored (in a subsequent CL). Bug: 22322814 Test: make -j 50 checkbuild make -j 50 test-art-host Change-Id: I8b096c1e2542f829eb456b4b057c71421b77d7e2
2017-09-20Refactor linker files from compiler/ to dex2oat/. Vladimir Marko
This shifts some code from the libart-compiler.so to dex2oat and reduces memory needed for JIT. We also avoid loading the libart-dexlayout.so for JIT but the memory savings are minimal (one shared clean page, two shared dirty pages and some per-app kernel mmap data) as the code has never been needed in memory by JIT. aosp_angler-userdebug file sizes (stripped): lib64/libart-compiler.so: 2989112 -> 2671888 (-310KiB) lib/libart-compiler.so: 2160816 -> 1939276 (-216KiB) bin/dex2oat: 141868 -> 368808 (+222KiB) LOAD/executable elf mapping sizes: lib64/libart-compiler.so: 2866308 -> 2555500 (-304KiB) lib/libart-compiler.so: 2050960 -> 1834836 (-211KiB) bin/dex2oat: 129316 -> 345916 (+212KiB) Test: m test-art-host-gtest Test: testrunner.py --host Test: cd art/; mma; cd - Change-Id: If62f02847a6cbb208eaf7e1f3e91af4663fa4a5f
2017-09-07Use mmapped boot image intern table for PIC app HLoadString. Vladimir Marko
Implement new HLoadString load kind for boot image strings referenced by PIC-compiled apps (i.e. prebuilts) that uses PC-relative load from a boot image InternTable mmapped into the apps .bss. This reduces the size of the PIC prebuilts that reference boot image strings compared to the kBssEntry as we can completely avoid the slow path and stack map. We separate the InternedStrings and ClassTable sections of the boot image (.art) file from the rest, aligning the start of the InternedStrings section to a page boundary. This may actually increase the size of the boot image file by a page but it also allows mprotecting() these tables as read-only. The ClassTable section is included in anticipation of a similar load kind for HLoadClass. Prebuilt services.odex for aosp_angler-userdebug (arm64): - before: 20862776 - after: 20308512 (-541KiB) Note that 92KiB savings could have been achieved by simply avoiding the read barrier, similar to the HLoadClass flag IsInBootImage(). Such flag is now unnecessary. Test: m test-art-host-gtest Test: testrunner.py --host Test: testrunner.py --host --pictest Test: testrunner.py --target on Nexus 6P. Test: testrunner.py --target --pictest on Nexus 6P. Test: Nexus 6P boots. Bug: 31951624 Change-Id: I5f2bf1fc0bb36a8483244317cfdfa69e192ef6c5
2017-07-24ART: Include cleanup Andreas Gampe
Let clang-format reorder the header includes. Derived with: * .clang-format: BasedOnStyle: Google IncludeIsMainRegex: '(_test|-inl)?$' * Steps: find . -name '*.cc' -o -name '*.h' | xargs sed -i.bak -e 's/^#include/ #include/' ; git commit -a -m 'ART: Include cleanup' git-clang-format -style=file HEAD^ manual inspection git commit -a --amend Test: mmma art Change-Id: Ia963a8ce3ce5f96b5e78acd587e26908c7a70d02
2017-06-05ART: More header cleanups Andreas Gampe
Pull out more dependencies through forward declarations. Test: m test-art-host Change-Id: I7d86726928937f788b956ec9eac91532d66d57ae
2016-12-20Fix incorrect string hash value extension during cross-compilation. Alexey Grebenkin
Previouly, having a 32-bit Android device and a 64-bit host to compile boot.oat could lead to an interning table be fulfilled using one hash function and be worked with using another hash function (which is caused by sign extension). Target case is any string with a negative .GetHashCode(). Test: test-art-host-gtest-intern_table_test Change-Id: I3f417e1ac990ef681f0651160292130e9b3632f0
2016-11-11Merge "Make empty checkpoint work while weak ref access is disabled." Hiroshi Yamauchi
2016-11-09Make empty checkpoint work while weak ref access is disabled. Hiroshi Yamauchi
Fix a potential race on PushOntoMarkStack for CC by running an empty checkpoint (while weak ref access is disabled). Bug: 32508093 Bug: 12687968 Test: test-art-host with CC/CMS, libartd boot with N9, Ritz EAAC. Change-Id: I3749bb525e7734804307ee16262355f3fc730312
2016-10-31Move intern table to ObjPtr Mathieu Chartier
Also moved StringLog to use a GcRoot. Also removed read barriers from lookup to prevent making weak strings strongly live more often than necessary. Bug: 31113334 Test: clean-oat-host && test-art-host CC baker Change-Id: I05586e125d5dfed8d184890468fd398c79f32619
2016-10-14Do not write empty class table and intern table to image. Vladimir Marko
And remove dead ClassLinker and InternTable code that would be erroneously triggered by not writing the tables. Test: m test-art-host Change-Id: I2520daa8d1231e16112d44e364a72d782fa32527
2016-08-30ART: SHARED_REQUIRES to REQUIRES_SHARED Andreas Gampe
This coincides with the actual attribute name and upstream usage. Preparation for deferring to libbase. Test: m Test: m test-art-host Change-Id: Ia8986b5dfd926ba772bf00b0a35eaf83596d8518
2016-03-29Optimizing: Improve const-string code generation. Vladimir Marko
For strings in the boot image, use either direct pointers or pc-relative addresses. For other strings, use PC-relative access to the dex cache arrays for AOT and direct address of the string's dex cache slot for JIT. For aosp_flounder-userdebug: - 32-bit boot.oat: -692KiB (-0.9%) - 64-bit boot.oat: -948KiB (-1.1%) - 32-bit dalvik cache total: -900KiB (-0.9%) - 64-bit dalvik cache total: -3672KiB (-1.5%) (contains more files than the 32-bit dalvik cache) For aosp_flounder-userdebug forced to compile PIC: - 32-bit boot.oat: -380KiB (-0.5%) - 64-bit boot.oat: -928KiB (-1.0%) - 32-bit dalvik cache total: -468KiB (-0.4%) - 64-bit dalvik cache total: -1928KiB (-0.8%) (contains more files than the 32-bit dalvik cache) Bug: 26884697 Change-Id: Iec7266ce67e6fedc107be78fab2e742a8dab2696
2016-01-25Revert "Revert "Load app images"" Mathieu Chartier
This reverts commit 1bc977cf2f8199311a97f2ba9431a184540e3e9c. Bug: 22858531 Change-Id: Ide00bf3a73a02cba3bb364177204ad1b13f70295
2016-01-23Revert "Load app images" Nicolas Geoffray
Fails when a method is duplicated (see test 097-duplicate-method) Bug: 22858531 This reverts commit f7fd970244f143b1abb956e29794c446e4d57f46. Change-Id: Ib30ae5be00cc568e799290be6b3c8f29cbbe4c20
2016-01-22Load app images Mathieu Chartier
Support in-place patching of the app image based on boot image location and app oat location. Only loads for art run test so far since we do not automatically generate app images for app installs. N5 maps launch time (~200 runs): Before: 930ms After: 878.18ms After + image class table: 864.57ms TODO: Oatdump support. Store class loaders as class roots in image. Bug: 22858531 Change-Id: I9cbc645645e62ea2ed1ad8e139e91af7d88514c1
2016-01-19Fix various typos in ART's comments and string literals. Roland Levillain
Change-Id: I85d628055b1a61647a77fef730c9631c234e22a2
2016-01-06Address some intern table comments Mathieu Chartier
Change-Id: I7ffaa463272015c2924ba03e006041daee498ad4
2016-01-06Re-enable adding intern table to image Mathieu Chartier
Changed intern table to have a stack of tables similarily to ClassTable. Adding an image intern table adds to the front of the intern table stack. Also some cleanup. Bug: 26317072 Change-Id: I7bbf9485b5dbbbf3707fed21e29de3beccfb8705
2015-10-16Change hash table load factors Mathieu Chartier
Changed class table and intern table load factors to query the runtime. The runtime returns load factors based on whether or not we are a low ram device. DescriptorEquals time for class linking goes from 10% -> 1.2% for compiling GmsCore with interpret only. Added test. Bug: 24917584 Change-Id: Iaaf5d2eab1b0c2d188d299e4bc1852cdb3801173
2015-09-03Some fixes for the CC collector. Hiroshi Yamauchi
- Remove a DCHECK in DisableMarkingCheckpoint, which caused occasional (false) failures. - Check the thread-local GetWeakRefAccessEnabled in boxed lambdas weak access. - Add missing BroadcastForNewAllocationRecords and BroadcastForNewWeakBoxedLambdas. The lack of the former caused occasional deadlocks in the ddmc test. - Remove the 'ensure system weaks disallowed' calls, which weren't useful and dead. Bug: 12687968 Change-Id: I33850c8d12e6e1a3aed1c2bb18eba263cbab76e8
2015-08-04Address some comments and clean up Mathieu Chartier
Change-Id: I538cf204f1c89d5fc81f8fc5e5800fcf1cf87359
2015-07-23Add some more uninterruptible annotations Mathieu Chartier
Added to mirror sites, class linker, and intern table. Bug: 20072211 Change-Id: I2224bcefefaab05d325f14844b1514e3d719e649