Home | History | Annotate | Download | only in bytecode
      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 8
     38 
     39 namespace JSC {
     40 
     41     // *Sigh*, If the JIT is enabled we need to track the stubRountine (of type 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 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 : FastAllocBase {
     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
    167