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 "PropertySlot.h" 35 #include "Structure.h" 36 #include "StructureChain.h" 37 #include <wtf/VectorTraits.h> 38 39 #define POLYMORPHIC_LIST_CACHE_SIZE 8 40 41 namespace JSC { 42 43 // *Sigh*, If the JIT is enabled we need to track the stubRountine (of type CodeLocationLabel), 44 // 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 45 // curently actually use PolymorphicAccessStructureLists, which we should). Anyway, this seems like the best 46 // solution for now - will need to something smarter if/when we actually want mixed-mode operation. 47 #if ENABLE(JIT) 48 typedef CodeLocationLabel PolymorphicAccessStructureListStubRoutineType; 49 #else 50 typedef void* PolymorphicAccessStructureListStubRoutineType; 51 #endif 52 53 class JSCell; 54 class Structure; 55 class StructureChain; 56 57 // 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. 58 struct PolymorphicAccessStructureList { 59 WTF_MAKE_FAST_ALLOCATED; 60 public: 61 struct PolymorphicStubInfo { 62 bool isChain; 63 PolymorphicAccessStructureListStubRoutineType stubRoutine; 64 WriteBarrier<Structure> base; 65 union { 66 WriteBarrierBase<Structure> proto; 67 WriteBarrierBase<StructureChain> chain; 68 } u; 69 70 void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base) 71 { 72 stubRoutine = _stubRoutine; 73 base.set(globalData, owner, _base); 74 u.proto.clear(); 75 isChain = false; 76 } 77 78 void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, Structure* _proto) 79 { 80 stubRoutine = _stubRoutine; 81 base.set(globalData, owner, _base); 82 u.proto.set(globalData, owner, _proto); 83 isChain = false; 84 } 85 86 void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain) 87 { 88 stubRoutine = _stubRoutine; 89 base.set(globalData, owner, _base); 90 u.chain.set(globalData, owner, _chain); 91 isChain = true; 92 } 93 } list[POLYMORPHIC_LIST_CACHE_SIZE]; 94 95 PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase) 96 { 97 list[0].set(globalData, owner, stubRoutine, firstBase); 98 } 99 100 PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, Structure* firstProto) 101 { 102 list[0].set(globalData, owner, stubRoutine, firstBase, firstProto); 103 } 104 105 PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain) 106 { 107 list[0].set(globalData, owner, stubRoutine, firstBase, firstChain); 108 } 109 110 void markAggregate(MarkStack& markStack, int count) 111 { 112 for (int i = 0; i < count; ++i) { 113 PolymorphicStubInfo& info = list[i]; 114 ASSERT(info.base); 115 116 markStack.append(&info.base); 117 if (info.u.proto && !info.isChain) 118 markStack.append(&info.u.proto); 119 if (info.u.chain && info.isChain) 120 markStack.append(&info.u.chain); 121 } 122 } 123 }; 124 125 struct Instruction { 126 Instruction(Opcode opcode) 127 { 128 #if !ENABLE(COMPUTED_GOTO_INTERPRETER) 129 // We have to initialize one of the pointer members to ensure that 130 // the entire struct is initialized, when opcode is not a pointer. 131 u.jsCell.clear(); 132 #endif 133 u.opcode = opcode; 134 } 135 136 Instruction(int operand) 137 { 138 // We have to initialize one of the pointer members to ensure that 139 // the entire struct is initialized in 64-bit. 140 u.jsCell.clear(); 141 u.operand = operand; 142 } 143 144 Instruction(JSGlobalData& globalData, JSCell* owner, Structure* structure) 145 { 146 u.structure.clear(); 147 u.structure.set(globalData, owner, structure); 148 } 149 Instruction(JSGlobalData& globalData, JSCell* owner, StructureChain* structureChain) 150 { 151 u.structureChain.clear(); 152 u.structureChain.set(globalData, owner, structureChain); 153 } 154 Instruction(JSGlobalData& globalData, JSCell* owner, JSCell* jsCell) 155 { 156 u.jsCell.clear(); 157 u.jsCell.set(globalData, owner, jsCell); 158 } 159 Instruction(PolymorphicAccessStructureList* polymorphicStructures) { u.polymorphicStructures = polymorphicStructures; } 160 Instruction(PropertySlot::GetValueFunc getterFunc) { u.getterFunc = getterFunc; } 161 162 union { 163 Opcode opcode; 164 int operand; 165 WriteBarrierBase<Structure> structure; 166 WriteBarrierBase<StructureChain> structureChain; 167 WriteBarrierBase<JSCell> jsCell; 168 PolymorphicAccessStructureList* polymorphicStructures; 169 PropertySlot::GetValueFunc getterFunc; 170 } u; 171 172 private: 173 Instruction(StructureChain*); 174 Instruction(Structure*); 175 }; 176 177 } // namespace JSC 178 179 namespace WTF { 180 181 template<> struct VectorTraits<JSC::Instruction> : VectorTraitsBase<true, JSC::Instruction> { }; 182 183 } // namespace WTF 184 185 #endif // Instruction_h 186