• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16/*
17 * Description:
18 * 1. This code tests the lazy deoptimization that occurs in stobjbyname.
19 *    After the JIT code for function 'Test2' is compiled,
20 *    modifying an HClass invalidates the function,
21 *    and subsequent accesses to it will detect this invalidation.
22 * 2. Test2 call ChangePrototypeValue inlined.
23 * 3. Test GC effect.
24 * 4. Test a function perform lazy deoptimization on two of the functions on the call stack.
25 */
26
27function ChangePrototypeValue2(obj, shouldChange) {
28    print("ChangeProto2 start.");
29    if (shouldChange) {
30        // Change the property 'x' at the second level of the prototype chain,
31        // triggering lazy deoptimization of the JIT-compiled 'Test2' function.
32        Object.defineProperty(obj.__proto__, 'y', {
33            set: function (value) {
34                this._y = 3;
35                print("Set value to 3.");
36            },
37            enumerable: true,
38            configurable: true
39        });
40        Object.defineProperty(obj.__proto__.__proto__, 'x', {
41            set: function (value) {
42                this._x = 2;
43                print("Set value to 2.");
44            },
45            enumerable: true,
46            configurable: true
47        });
48    }
49    print("ChangeProto2 end.");
50}
51
52function ChangePrototypeValue(obj, shouldChange) {
53    print("ChangeProto start.");
54    ChangePrototypeValue2(obj, shouldChange);
55    obj.y = 1;
56    print("obj.y: ", obj.y);
57    print("ChangeProto end.");
58    // Additional code to prevent aggressive inlining.
59    let test = {};
60    test.x; test.x; test.x; test.x; test.x; test.x; test.x; test.x; test.x; test.x;
61    test.x; test.x; test.x; test.x; test.x; test.x; test.x; test.x; test.x; test.x;
62    test.x; test.x; test.x; test.x; test.x; test.x; test.x; test.x; test.x; test.x;
63    test.x; test.x; test.x; test.x; test.x; test.x; test.x; test.x; test.x; test.x;
64}
65
66
67// Test function that calls ChangePrototypeValue and prints the value of obj.x.
68function Test2(obj, shouldChange) {
69    print("Test2 start.");
70    ChangePrototypeValue(obj, shouldChange);
71    obj.x = 1;
72    print("Test2 obj.x :", obj.x);
73    print("Test2 end.");
74}
75
76class A {}
77class B extends A {}
78class C extends B {}
79
80// Set the initial value of property x through A.prototype.
81A.prototype.x = 1;
82
83const c = new C();
84
85// Initial call to test without changing the prototype's property.
86Test2(c, false);
87
88ArkTools.jitCompileAsync(Test2);
89print(ArkTools.waitJitCompileFinish(Test2));
90
91ArkTools.jitCompileAsync(ChangePrototypeValue);
92print(ArkTools.waitJitCompileFinish(ChangePrototypeValue));
93
94print("------------------------------------------------------");
95// Call test with the flag set to true to modify the prototype property, triggering lazy deoptimization.
96const c2 = new C();
97Test2(c2, true);