File: ExpressionInfoInlines.h

package info (click to toggle)
webkit2gtk 2.48.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 429,620 kB
  • sloc: cpp: 3,696,936; javascript: 194,444; ansic: 169,997; python: 46,499; asm: 19,276; ruby: 18,528; perl: 16,602; xml: 4,650; yacc: 2,360; sh: 2,098; java: 1,993; lex: 1,327; pascal: 366; makefile: 298
file content (122 lines) | stat: -rw-r--r-- 5,626 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
 * Copyright (C) 2024 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "ExpressionInfo.h"

namespace JSC {

template<typename RemapFunc>
void ExpressionInfo::Encoder::remap(Vector<unsigned>&& adjustmentLabelPoints, RemapFunc remapFunc)
{
    if (!adjustmentLabelPoints.size())
        return; // Nothing to adjust.

    // Pad the end with a value that exceeds all other bytecodeIndexes.
    // This way, currentLabel below will always has a meaningful value
    // to compare instPC against.
    adjustmentLabelPoints.append(UINT_MAX);

    ExpressionInfo::Decoder decoder(m_expressionInfoEncodedInfo);
    unsigned numEncodedInfo = m_expressionInfoEncodedInfo.size();

    // These are the types of adjustments that we need to handle:
    // 1. bytecode got inserted before a LabelPoint.
    // 2. bytecode got inserted after the LabelPoint.
    // 3. bytecode got deleted after the LabelPoint.
    //
    // This means that we only need to do a remap of InstPC for the following:
    //
    // a. the EncodedInfo Entry at a LabelPoint InstPC (due to (1) above).
    //
    //    In this case, the InstPC increased. Our remap will add a delta for the increment.
    //    Since our EncodedInfo are expressed as deltas from the previous Entry, once an
    //    adjustment has been applied, subsequent entries will just pick it up for free.
    //
    // b. the EncodedInfo Entry right after the LabelPoint InstPC (due to (2) and (3) above).
    //
    //    Inserting / Removing bytecode after the LabelPoint affects the InstPC of bytecode
    //    that follows the LabelPoint starting with the bytecode immediately after. There may
    //    or may not be any ExpressionInfo Entry for these bytecode. However, we can just be
    //    conservative, and go ahead to compute the remap for the next Entry anyway. After
    //    that, our delta cummulation scheme takes care of the rest.
    //
    //    There's also a chance that the next Entry is already beyond the next LabelPoint.
    //    This is also fine because our remap is computed based on the absolute value of its
    //    InstPC, not its relative value. Hence, there is no adjusment error: we'll always
    //    get the correct remapped InstPC value.
    //
    // c. the EncodedInfo Entry that start with an AbsInstPC.
    //
    //    Above, we pointed out that because our EncodedInfo are expressed as deltas from
    //    the previous Entry, adjustments are picked up for free. There is one exception:
    //    AbsInstPC. AbsInstPC does not build on cummulative deltas. So, whenever we see an
    //    AbsInstPC, we must also remap it.

    unsigned adjustmentIndex = 0;
    InstPC currentLabel = adjustmentLabelPoints[adjustmentIndex];
    bool needToAdjustLabelAfter = false;
    unsigned cummulativeDelta = 0;

    while (decoder.decode() != IterationStatus::Done) {
        bool isAbsInstPC = decoder.currentInfo()->isAbsInstPC();
        bool needRemap = isAbsInstPC;

        InstPC instPC = decoder.instPC();
        if (instPC >= currentLabel) {
            needToAdjustLabelAfter = true;
            needRemap = true;
            currentLabel = adjustmentLabelPoints[++adjustmentIndex];

        } else if (needToAdjustLabelAfter) {
            needToAdjustLabelAfter = false;
            needRemap = true;
        }

        unsigned instPCDelta;
        if (needRemap) {
            if (isAbsInstPC)
                cummulativeDelta = 0;
            instPCDelta = remapFunc(instPC) - instPC - cummulativeDelta;
            if (instPCDelta || isAbsInstPC) {
                adjustInstPC(decoder.currentInfo(), instPCDelta);

                // adjustInstPC() may have resized and reallocated m_expressionInfoEncodedInfo.
                // So, we need to re-compute endInfo. info will be re-computed at the top of the loop.
                decoder.recacheInfo(m_expressionInfoEncodedInfo);
                cummulativeDelta += instPCDelta;
            }
        }
    }
    m_numberOfEncodedInfoExtensions = m_expressionInfoEncodedInfo.size() - numEncodedInfo;

    // Now, let's remap the Chapter startInstPCs. Their startEncodedInfoIndex will not change because
    // the above remap algorithm does in place remapping.
    for (auto& chapter : m_expressionInfoChapters)
        chapter.startInstPC = remapFunc(chapter.startInstPC);
}

} // namespace JSC