314fda4dd4e3710cf5a2c5b81b9630e3f39ee437
[WebKit.git] / JavaScriptCore / bytecode / Instruction.h
1 /*
2  * Copyright (C) 2008 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  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #ifndef Instruction_h
30 #define Instruction_h
31
32 #include "MacroAssembler.h"
33 #include "Opcode.h"
34 #include "Structure.h"
35 #include <wtf/VectorTraits.h>
36
37 #define POLYMORPHIC_LIST_CACHE_SIZE 4
38
39 namespace JSC {
40
41     // *Sigh*, If the JIT is enabled we need to track the stubRountine (of type MacroAssembler::CodeLocationLabel),
42     // 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
43     // curently actually use PolymorphicAccessStructureLists, which we should).  Anyway, this seems like the best
44     // solution for now - will need to something smarter if/when we actually want mixed-mode operation.
45 #if ENABLE(JIT)
46     typedef MacroAssembler::CodeLocationLabel PolymorphicAccessStructureListStubRoutineType;
47 #else
48     typedef void* PolymorphicAccessStructureListStubRoutineType;
49 #endif
50
51     class JSCell;
52     class Structure;
53     class StructureChain;
54
55     // 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.
56     struct PolymorphicAccessStructureList {
57         struct PolymorphicStubInfo {
58             bool isChain;
59             PolymorphicAccessStructureListStubRoutineType stubRoutine;
60             Structure* base;
61             union {
62                 Structure* proto;
63                 StructureChain* chain;
64             } u;
65
66             void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base)
67             {
68                 stubRoutine = _stubRoutine;
69                 base = _base;
70                 u.proto = 0;
71                 isChain = false;
72             }
73             
74             void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, Structure* _proto)
75             {
76                 stubRoutine = _stubRoutine;
77                 base = _base;
78                 u.proto = _proto;
79                 isChain = false;
80             }
81             
82             void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain)
83             {
84                 stubRoutine = _stubRoutine;
85                 base = _base;
86                 u.chain = _chain;
87                 isChain = true;
88             }
89         } list[POLYMORPHIC_LIST_CACHE_SIZE];
90         
91         PolymorphicAccessStructureList(PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase)
92         {
93             list[0].set(stubRoutine, firstBase);
94         }
95
96         PolymorphicAccessStructureList(PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, Structure* firstProto)
97         {
98             list[0].set(stubRoutine, firstBase, firstProto);
99         }
100
101         PolymorphicAccessStructureList(PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain)
102         {
103             list[0].set(stubRoutine, firstBase, firstChain);
104         }
105
106         void derefStructures(int count)
107         {
108             for (int i = 0; i < count; ++i) {
109                 PolymorphicStubInfo& info = list[i];
110
111                 ASSERT(info.base);
112                 info.base->deref();
113
114                 if (info.u.proto) {
115                     if (info.isChain)
116                         info.u.chain->deref();
117                     else
118                         info.u.proto->deref();
119                 }
120             }
121         }
122     };
123
124     struct Instruction {
125         Instruction(Opcode opcode)
126         {
127 #if !HAVE(COMPUTED_GOTO)
128             // We have to initialize one of the pointer members to ensure that
129             // the entire struct is initialized, when opcode is not a pointer.
130             u.jsCell = 0;
131 #endif
132             u.opcode = opcode;
133         }
134
135         Instruction(int operand)
136         {
137             // We have to initialize one of the pointer members to ensure that
138             // the entire struct is initialized in 64-bit.
139             u.jsCell = 0;
140             u.operand = operand;
141         }
142
143         Instruction(Structure* structure) { u.structure = structure; }
144         Instruction(StructureChain* structureChain) { u.structureChain = structureChain; }
145         Instruction(JSCell* jsCell) { u.jsCell = jsCell; }
146         Instruction(PolymorphicAccessStructureList* polymorphicStructures) { u.polymorphicStructures = polymorphicStructures; }
147
148         union {
149             Opcode opcode;
150             int operand;
151             Structure* structure;
152             StructureChain* structureChain;
153             JSCell* jsCell;
154             PolymorphicAccessStructureList* polymorphicStructures;
155         } u;
156     };
157
158 } // namespace JSC
159
160 namespace WTF {
161
162     template<> struct VectorTraits<JSC::Instruction> : VectorTraitsBase<true, JSC::Instruction> { };
163
164 } // namespace WTF
165
166 #endif // Instruction_h