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 "Opcode.h" 33 #include "Structure.h" 34 #include <wtf/VectorTraits.h> 35 36 #define POLYMORPHIC_LIST_CACHE_SIZE 4 37 38 namespace JSC { 39 40 class JSCell; 41 class Structure; 42 class StructureChain; 43 44 // 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. 45 struct PolymorphicAccessStructureList { 46 struct PolymorphicStubInfo { 47 bool isChain; 48 void* stubRoutine; 49 Structure* base; 50 union { 51 Structure* proto; 52 StructureChain* chain; 53 } u; 54 setPolymorphicAccessStructureList::PolymorphicStubInfo55 void set(void* _stubRoutine, Structure* _base) 56 { 57 stubRoutine = _stubRoutine; 58 base = _base; 59 u.proto = 0; 60 isChain = false; 61 } 62 setPolymorphicAccessStructureList::PolymorphicStubInfo63 void set(void* _stubRoutine, Structure* _base, Structure* _proto) 64 { 65 stubRoutine = _stubRoutine; 66 base = _base; 67 u.proto = _proto; 68 isChain = false; 69 } 70 setPolymorphicAccessStructureList::PolymorphicStubInfo71 void set(void* _stubRoutine, Structure* _base, StructureChain* _chain) 72 { 73 stubRoutine = _stubRoutine; 74 base = _base; 75 u.chain = _chain; 76 isChain = true; 77 } 78 } list[POLYMORPHIC_LIST_CACHE_SIZE]; 79 PolymorphicAccessStructureListPolymorphicAccessStructureList80 PolymorphicAccessStructureList(void* stubRoutine, Structure* firstBase) 81 { 82 list[0].set(stubRoutine, firstBase); 83 } 84 PolymorphicAccessStructureListPolymorphicAccessStructureList85 PolymorphicAccessStructureList(void* stubRoutine, Structure* firstBase, Structure* firstProto) 86 { 87 list[0].set(stubRoutine, firstBase, firstProto); 88 } 89 PolymorphicAccessStructureListPolymorphicAccessStructureList90 PolymorphicAccessStructureList(void* stubRoutine, Structure* firstBase, StructureChain* firstChain) 91 { 92 list[0].set(stubRoutine, firstBase, firstChain); 93 } 94 derefStructuresPolymorphicAccessStructureList95 void derefStructures(int count) 96 { 97 for (int i = 0; i < count; ++i) { 98 PolymorphicStubInfo& info = list[i]; 99 100 ASSERT(info.base); 101 info.base->deref(); 102 103 if (info.u.proto) { 104 if (info.isChain) 105 info.u.chain->deref(); 106 else 107 info.u.proto->deref(); 108 } 109 } 110 } 111 }; 112 113 struct Instruction { InstructionInstruction114 Instruction(Opcode opcode) 115 { 116 #if !HAVE(COMPUTED_GOTO) 117 // We have to initialize one of the pointer members to ensure that 118 // the entire struct is initialized, when opcode is not a pointer. 119 u.jsCell = 0; 120 #endif 121 u.opcode = opcode; 122 } 123 InstructionInstruction124 Instruction(int operand) 125 { 126 // We have to initialize one of the pointer members to ensure that 127 // the entire struct is initialized in 64-bit. 128 u.jsCell = 0; 129 u.operand = operand; 130 } 131 InstructionInstruction132 Instruction(Structure* structure) { u.structure = structure; } InstructionInstruction133 Instruction(StructureChain* structureChain) { u.structureChain = structureChain; } InstructionInstruction134 Instruction(JSCell* jsCell) { u.jsCell = jsCell; } InstructionInstruction135 Instruction(PolymorphicAccessStructureList* polymorphicStructures) { u.polymorphicStructures = polymorphicStructures; } 136 137 union { 138 Opcode opcode; 139 int operand; 140 Structure* structure; 141 StructureChain* structureChain; 142 JSCell* jsCell; 143 PolymorphicAccessStructureList* polymorphicStructures; 144 } u; 145 }; 146 147 } // namespace JSC 148 149 namespace WTF { 150 151 template<> struct VectorTraits<JSC::Instruction> : VectorTraitsBase<true, JSC::Instruction> { }; 152 153 } // namespace WTF 154 155 #endif // Instruction_h 156