1635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/*
2635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (C) 2008 Apple Inc. All rights reserved.
3635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
4635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Redistribution and use in source and binary forms, with or without
5635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * modification, are permitted provided that the following conditions
6635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * are met:
7635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
8635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 1.  Redistributions of source code must retain the above copyright
9635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *     notice, this list of conditions and the following disclaimer.
10635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 2.  Redistributions in binary form must reproduce the above copyright
11635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *     notice, this list of conditions and the following disclaimer in the
12635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *     documentation and/or other materials provided with the distribution.
13635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *     its contributors may be used to endorse or promote products derived
15635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *     from this software without specific prior written permission.
16635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project *
17635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project */
28635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#ifndef Instruction_h
30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#define Instruction_h
31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
328f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#include "MacroAssembler.h"
33635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Opcode.h"
34dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "PropertySlot.h"
35635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "Structure.h"
362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include "StructureChain.h"
37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <wtf/VectorTraits.h>
38635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#define POLYMORPHIC_LIST_CACHE_SIZE 8
40635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
41635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectnamespace JSC {
42635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    // *Sigh*, If the JIT is enabled we need to track the stubRountine (of type CodeLocationLabel),
448f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // If the JIT is not in use we don't actually need the variable (that said, if the JIT is not in use we don't
458f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // curently actually use PolymorphicAccessStructureLists, which we should).  Anyway, this seems like the best
468f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    // solution for now - will need to something smarter if/when we actually want mixed-mode operation.
478f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#if ENABLE(JIT)
480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    typedef CodeLocationLabel PolymorphicAccessStructureListStubRoutineType;
498f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#else
508f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian    typedef void* PolymorphicAccessStructureListStubRoutineType;
518f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif
528f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian
53635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    class JSCell;
54635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    class Structure;
55635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    class StructureChain;
56635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
57635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    // Structure used by op_get_by_id_self_list and op_get_by_id_proto_list instruction to hold data off the main opcode stream.
58ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    struct PolymorphicAccessStructureList {
59ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch        WTF_MAKE_FAST_ALLOCATED;
60ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch    public:
61635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        struct PolymorphicStubInfo {
62635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            bool isChain;
638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian            PolymorphicAccessStructureListStubRoutineType stubRoutine;
642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            WriteBarrier<Structure> base;
65635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            union {
662daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                WriteBarrierBase<Structure> proto;
672bde8e466a4451c7319e3a072d118917957d6554Steve Block                WriteBarrierBase<StructureChain> chain;
68635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            } u;
69635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
702daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base)
71635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            {
72635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                stubRoutine = _stubRoutine;
732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                base.set(globalData, owner, _base);
742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                u.proto.clear();
75635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                isChain = false;
76635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
77635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
782daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, Structure* _proto)
79635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            {
80635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                stubRoutine = _stubRoutine;
812daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                base.set(globalData, owner, _base);
822daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                u.proto.set(globalData, owner, _proto);
83635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                isChain = false;
84635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
85635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
862bde8e466a4451c7319e3a072d118917957d6554Steve Block            void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain)
87635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            {
88635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                stubRoutine = _stubRoutine;
892daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                base.set(globalData, owner, _base);
902bde8e466a4451c7319e3a072d118917957d6554Steve Block                u.chain.set(globalData, owner, _chain);
91635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project                isChain = true;
92635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            }
93635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        } list[POLYMORPHIC_LIST_CACHE_SIZE];
94635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase)
96635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        {
972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            list[0].set(globalData, owner, stubRoutine, firstBase);
98635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
99635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, Structure* firstProto)
101635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        {
1022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            list[0].set(globalData, owner, stubRoutine, firstBase, firstProto);
103635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
104635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1052bde8e466a4451c7319e3a072d118917957d6554Steve Block        PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain)
106635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        {
1072bde8e466a4451c7319e3a072d118917957d6554Steve Block            list[0].set(globalData, owner, stubRoutine, firstBase, firstChain);
108635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
109635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1102bde8e466a4451c7319e3a072d118917957d6554Steve Block        void markAggregate(MarkStack& markStack, int count)
1112bde8e466a4451c7319e3a072d118917957d6554Steve Block        {
1122bde8e466a4451c7319e3a072d118917957d6554Steve Block            for (int i = 0; i < count; ++i) {
1132bde8e466a4451c7319e3a072d118917957d6554Steve Block                PolymorphicStubInfo& info = list[i];
1142bde8e466a4451c7319e3a072d118917957d6554Steve Block                ASSERT(info.base);
1152bde8e466a4451c7319e3a072d118917957d6554Steve Block
1162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                markStack.append(&info.base);
1172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                if (info.u.proto && !info.isChain)
1182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                    markStack.append(&info.u.proto);
1192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch                if (info.u.chain && info.isChain)
1202bde8e466a4451c7319e3a072d118917957d6554Steve Block                    markStack.append(&info.u.chain);
1212bde8e466a4451c7319e3a072d118917957d6554Steve Block            }
1222bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
123635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    };
124635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
125635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    struct Instruction {
126635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        Instruction(Opcode opcode)
127635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        {
128e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#if !ENABLE(COMPUTED_GOTO_INTERPRETER)
129635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // We have to initialize one of the pointer members to ensure that
130635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // the entire struct is initialized, when opcode is not a pointer.
1312bde8e466a4451c7319e3a072d118917957d6554Steve Block            u.jsCell.clear();
132635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
133635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            u.opcode = opcode;
134635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
135635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
136635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        Instruction(int operand)
137635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        {
138635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // We have to initialize one of the pointer members to ensure that
139635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            // the entire struct is initialized in 64-bit.
1402bde8e466a4451c7319e3a072d118917957d6554Steve Block            u.jsCell.clear();
141635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            u.operand = operand;
142635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        }
143635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
1442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        Instruction(JSGlobalData& globalData, JSCell* owner, Structure* structure)
1452daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        {
1462daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            u.structure.clear();
1472daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            u.structure.set(globalData, owner, structure);
1482daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        }
1492bde8e466a4451c7319e3a072d118917957d6554Steve Block        Instruction(JSGlobalData& globalData, JSCell* owner, StructureChain* structureChain)
1502bde8e466a4451c7319e3a072d118917957d6554Steve Block        {
1512bde8e466a4451c7319e3a072d118917957d6554Steve Block            u.structureChain.clear();
1522bde8e466a4451c7319e3a072d118917957d6554Steve Block            u.structureChain.set(globalData, owner, structureChain);
1532bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
1542bde8e466a4451c7319e3a072d118917957d6554Steve Block        Instruction(JSGlobalData& globalData, JSCell* owner, JSCell* jsCell)
1552bde8e466a4451c7319e3a072d118917957d6554Steve Block        {
1562bde8e466a4451c7319e3a072d118917957d6554Steve Block            u.jsCell.clear();
1572bde8e466a4451c7319e3a072d118917957d6554Steve Block            u.jsCell.set(globalData, owner, jsCell);
1582bde8e466a4451c7319e3a072d118917957d6554Steve Block        }
159635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        Instruction(PolymorphicAccessStructureList* polymorphicStructures) { u.polymorphicStructures = polymorphicStructures; }
160dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        Instruction(PropertySlot::GetValueFunc getterFunc) { u.getterFunc = getterFunc; }
161635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
162635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        union {
163635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            Opcode opcode;
164635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            int operand;
1652daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch            WriteBarrierBase<Structure> structure;
1662bde8e466a4451c7319e3a072d118917957d6554Steve Block            WriteBarrierBase<StructureChain> structureChain;
1672bde8e466a4451c7319e3a072d118917957d6554Steve Block            WriteBarrierBase<JSCell> jsCell;
168635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project            PolymorphicAccessStructureList* polymorphicStructures;
169dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            PropertySlot::GetValueFunc getterFunc;
170635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project        } u;
1712daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1722daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    private:
1732daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        Instruction(StructureChain*);
1742daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        Instruction(Structure*);
175635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    };
176635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
177635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} // namespace JSC
178635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
179635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectnamespace WTF {
180635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
181635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    template<> struct VectorTraits<JSC::Instruction> : VectorTraitsBase<true, JSC::Instruction> { };
182635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
183635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} // namespace WTF
184635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project
185635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif // Instruction_h
186