diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGVariableEvent.h')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGVariableEvent.h | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGVariableEvent.h b/Source/JavaScriptCore/dfg/DFGVariableEvent.h new file mode 100644 index 000000000..a491a3ebf --- /dev/null +++ b/Source/JavaScriptCore/dfg/DFGVariableEvent.h @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2012 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DFGVariableEvent_h +#define DFGVariableEvent_h + +#include <wtf/Platform.h> + +#if ENABLE(DFG_JIT) + +#include "DFGCommon.h" +#include "DataFormat.h" +#include "MacroAssembler.h" +#include <stdio.h> + +namespace JSC { namespace DFG { + +enum VariableEventKind { + // Marks the beginning of a checkpoint. If you interpret the variable + // events starting at a Reset point then you'll get everything you need. + Reset, + + // Node births. Points in the code where a node becomes relevant for OSR. + // It may be the point where it is actually born (i.e. assigned) or it may + // be a later point, if it's only later in the sequence of instructions + // that we start to care about this node. + BirthToFill, + BirthToSpill, + + // Events related to how a node is represented. + Fill, + Spill, + + // Death of a node - after this we no longer care about this node. + Death, + + // A MovHint means that a node is being associated with a bytecode operand, + // but that it has not been stored into that operand. + MovHint, + + // A SetLocalEvent means that a node's value has actually been stored into the + // bytecode operand that it's associated with. + SetLocalEvent, + + // Used to indicate an uninitialized VariableEvent. Don't use for other + // purposes. + InvalidEventKind +}; + +union VariableRepresentation { + MacroAssembler::RegisterID gpr; + MacroAssembler::FPRegisterID fpr; +#if USE(JSVALUE32_64) + struct { + MacroAssembler::RegisterID tagGPR; + MacroAssembler::RegisterID payloadGPR; + } pair; +#endif + int32_t virtualReg; +}; + +class VariableEvent { +public: + VariableEvent() + : m_kind(InvalidEventKind) + { + } + + static VariableEvent reset() + { + VariableEvent event; + event.m_kind = Reset; + return event; + } + + static VariableEvent fillGPR(VariableEventKind kind, NodeIndex nodeIndex, MacroAssembler::RegisterID gpr, DataFormat dataFormat) + { + ASSERT(kind == BirthToFill || kind == Fill); + ASSERT(dataFormat != DataFormatDouble); +#if USE(JSVALUE32_64) + ASSERT(!(dataFormat & DataFormatJS)); +#endif + VariableEvent event; + event.m_index = nodeIndex; + event.u.gpr = gpr; + event.m_kind = kind; + event.m_dataFormat = dataFormat; + return event; + } + +#if USE(JSVALUE32_64) + static VariableEvent fillPair(VariableEventKind kind, NodeIndex nodeIndex, MacroAssembler::RegisterID tagGPR, MacroAssembler::RegisterID payloadGPR) + { + ASSERT(kind == BirthToFill || kind == Fill); + VariableEvent event; + event.m_index = nodeIndex; + event.u.pair.tagGPR = tagGPR; + event.u.pair.payloadGPR = payloadGPR; + event.m_kind = kind; + event.m_dataFormat = DataFormatJS; + return event; + } +#endif // USE(JSVALUE32_64) + + static VariableEvent fillFPR(VariableEventKind kind, NodeIndex nodeIndex, MacroAssembler::FPRegisterID fpr) + { + ASSERT(kind == BirthToFill || kind == Fill); + VariableEvent event; + event.m_index = nodeIndex; + event.u.fpr = fpr; + event.m_kind = kind; + event.m_dataFormat = DataFormatDouble; + return event; + } + + static VariableEvent spill(VariableEventKind kind, NodeIndex nodeIndex, VirtualRegister virtualRegister, DataFormat format) + { + ASSERT(kind == BirthToSpill || kind == Spill); + VariableEvent event; + event.m_index = nodeIndex; + event.u.virtualReg = virtualRegister; + event.m_kind = kind; + event.m_dataFormat = format; + return event; + } + + static VariableEvent death(NodeIndex nodeIndex) + { + VariableEvent event; + event.m_index = nodeIndex; + event.m_kind = Death; + return event; + } + + static VariableEvent setLocal(int operand, DataFormat format) + { + VariableEvent event; + event.u.virtualReg = operand; + event.m_kind = SetLocalEvent; + event.m_dataFormat = format; + return event; + } + + static VariableEvent movHint(NodeIndex nodeIndex, int operand) + { + VariableEvent event; + event.m_index = nodeIndex; + event.u.virtualReg = operand; + event.m_kind = MovHint; + return event; + } + + VariableEventKind kind() const + { + return static_cast<VariableEventKind>(m_kind); + } + + NodeIndex nodeIndex() const + { + ASSERT(m_kind == BirthToFill || m_kind == Fill + || m_kind == BirthToSpill || m_kind == Spill + || m_kind == Death || m_kind == MovHint); + return m_index; + } + + DataFormat dataFormat() const + { + ASSERT(m_kind == BirthToFill || m_kind == Fill + || m_kind == BirthToSpill || m_kind == Spill + || m_kind == SetLocalEvent); + return static_cast<DataFormat>(m_dataFormat); + } + + MacroAssembler::RegisterID gpr() const + { + ASSERT(m_kind == BirthToFill || m_kind == Fill); + ASSERT(m_dataFormat); + ASSERT(m_dataFormat != DataFormatDouble); +#if USE(JSVALUE32_64) + ASSERT(!(m_dataFormat & DataFormatJS)); +#endif + return u.gpr; + } + +#if USE(JSVALUE32_64) + MacroAssembler::RegisterID tagGPR() const + { + ASSERT(m_kind == BirthToFill || m_kind == Fill); + ASSERT(m_dataFormat & DataFormatJS); + return u.pair.tagGPR; + } + MacroAssembler::RegisterID payloadGPR() const + { + ASSERT(m_kind == BirthToFill || m_kind == Fill); + ASSERT(m_dataFormat & DataFormatJS); + return u.pair.payloadGPR; + } +#endif // USE(JSVALUE32_64) + + MacroAssembler::FPRegisterID fpr() const + { + ASSERT(m_kind == BirthToFill || m_kind == Fill); + ASSERT(m_dataFormat == DataFormatDouble); + return u.fpr; + } + + VirtualRegister virtualRegister() const + { + ASSERT(m_kind == BirthToSpill || m_kind == Spill); + return static_cast<VirtualRegister>(u.virtualReg); + } + + int operand() const + { + ASSERT(m_kind == SetLocalEvent || m_kind == MovHint); + return u.virtualReg; + } + + const VariableRepresentation& variableRepresentation() const { return u; } + + void dump(FILE*) const; + +private: + void dumpFillInfo(const char* name, FILE*) const; + void dumpSpillInfo(const char* name, FILE*) const; + + NodeIndex m_index; + + // For BirthToFill, Fill: + // - The GPR or FPR, or a GPR pair. + // For BirthToSpill, Spill: + // - The virtual register. + // For MovHint, SetLocalEvent: + // - The bytecode operand. + // For Death: + // - Unused. + VariableRepresentation u; + + int8_t m_kind; + int8_t m_dataFormat; +}; + +} } // namespace JSC::DFG + +#endif // ENABLE(DFG_JIT) + +#endif // DFGVariableEvent_h + |