1/*
2 * Copyright (C) 2014 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef PolymorphicGetByIdList_h
27#define PolymorphicGetByIdList_h
28
29#if ENABLE(JIT)
30
31#include "CodeOrigin.h"
32#include "MacroAssembler.h"
33#include "Opcode.h"
34#include "Structure.h"
35#include <wtf/Vector.h>
36
37namespace JSC {
38
39class CodeBlock;
40struct StructureStubInfo;
41
42class GetByIdAccess {
43public:
44    enum AccessType {
45        Invalid,
46        SimpleInline, // This is the patched inline access.
47        SimpleStub, // This is a stub.
48        WatchedStub,
49        Getter,
50        CustomGetter
51    };
52
53    GetByIdAccess()
54        : m_type(Invalid)
55        , m_chainCount(0)
56    {
57    }
58
59    GetByIdAccess(
60        VM&, JSCell* owner, AccessType, PassRefPtr<JITStubRoutine>, Structure*,
61        StructureChain* = 0, unsigned chainCount = 0);
62
63    ~GetByIdAccess();
64
65    static GetByIdAccess fromStructureStubInfo(StructureStubInfo&);
66
67    bool isSet() const { return m_type != Invalid; }
68    bool operator!() const { return !isSet(); }
69
70    AccessType type() const { return m_type; }
71
72    Structure* structure() const { return m_structure.get(); }
73
74    StructureChain* chain() const { return m_chain.get(); }
75    unsigned chainCount() const { return m_chainCount; }
76
77    JITStubRoutine* stubRoutine() const
78    {
79        ASSERT(isSet());
80        return m_stubRoutine.get();
81    }
82
83    bool doesCalls() const { return type() == Getter || type() == CustomGetter; }
84    bool isWatched() const { return type() == WatchedStub; }
85    bool isSimple() const { return !doesCalls() && !isWatched(); }
86
87    bool visitWeak(RepatchBuffer&) const;
88
89private:
90    friend class CodeBlock;
91
92    AccessType m_type;
93    unsigned m_chainCount;
94    WriteBarrier<Structure> m_structure;
95    WriteBarrier<StructureChain> m_chain;
96    RefPtr<JITStubRoutine> m_stubRoutine;
97};
98
99class PolymorphicGetByIdList {
100    WTF_MAKE_FAST_ALLOCATED;
101public:
102    // Either creates a new polymorphic get list, or returns the one that is already in
103    // place.
104    static PolymorphicGetByIdList* from(StructureStubInfo&);
105
106    ~PolymorphicGetByIdList();
107
108    MacroAssemblerCodePtr currentSlowPathTarget(StructureStubInfo& stubInfo) const;
109
110    void addAccess(const GetByIdAccess&);
111
112    bool isEmpty() const { return m_list.isEmpty(); }
113    unsigned size() const { return m_list.size(); }
114    bool isFull() const;
115    bool isAlmostFull() const; // True if adding an element would make isFull() true.
116    const GetByIdAccess& at(unsigned i) const { return m_list[i]; }
117    const GetByIdAccess& operator[](unsigned i) const { return m_list[i]; }
118
119    bool didSelfPatching() const; // Are any of the accesses SimpleInline?
120
121    bool visitWeak(RepatchBuffer&) const;
122
123private:
124    friend class CodeBlock;
125
126    PolymorphicGetByIdList(StructureStubInfo&);
127
128    Vector<GetByIdAccess, 2> m_list;
129};
130
131} // namespace JSC
132
133#endif // ENABLE(JIT)
134
135#endif // PolymorphicGetByIdList_h
136
137