]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - dfg/DFGJITCodeGenerator.cpp
JavaScriptCore-1097.3.tar.gz
[apple/javascriptcore.git] / dfg / DFGJITCodeGenerator.cpp
diff --git a/dfg/DFGJITCodeGenerator.cpp b/dfg/DFGJITCodeGenerator.cpp
deleted file mode 100644 (file)
index 781edbb..0000000
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * Copyright (C) 2011 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. 
- */
-
-#include "config.h"
-#include "DFGJITCodeGenerator.h"
-
-#if ENABLE(DFG_JIT)
-
-#include "DFGNonSpeculativeJIT.h"
-#include "DFGSpeculativeJIT.h"
-#include "LinkBuffer.h"
-
-namespace JSC { namespace DFG {
-
-GPRReg JITCodeGenerator::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat)
-{
-    Node& node = m_jit.graph()[nodeIndex];
-    VirtualRegister virtualRegister = node.virtualRegister();
-    GenerationInfo& info = m_generationInfo[virtualRegister];
-
-    if (info.registerFormat() == DataFormatNone) {
-        GPRReg gpr = allocate();
-
-        if (node.isConstant()) {
-            m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
-            if (isInt32Constant(nodeIndex)) {
-                m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
-                info.fillInteger(gpr);
-                returnFormat = DataFormatInteger;
-                return gpr;
-            }
-            if (isDoubleConstant(nodeIndex)) {
-                JSValue jsValue = jsNumber(valueOfDoubleConstant(nodeIndex));
-                m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
-            } else {
-                ASSERT(isJSConstant(nodeIndex));
-                JSValue jsValue = valueOfJSConstant(nodeIndex);
-                m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
-            }
-        } else {
-            ASSERT(info.spillFormat() == DataFormatJS || info.spillFormat() == DataFormatJSInteger);
-            m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
-            m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
-        }
-
-        // Since we statically know that we're filling an integer, and values
-        // in the RegisterFile are boxed, this must be DataFormatJSInteger.
-        // We will check this with a jitAssert below.
-        info.fillJSValue(gpr, DataFormatJSInteger);
-        unlock(gpr);
-    }
-
-    switch (info.registerFormat()) {
-    case DataFormatNone:
-        // Should have filled, above.
-    case DataFormatJSDouble:
-    case DataFormatDouble:
-    case DataFormatJS:
-    case DataFormatCell:
-    case DataFormatJSCell:
-        // Should only be calling this function if we know this operand to be integer.
-        ASSERT_NOT_REACHED();
-
-    case DataFormatJSInteger: {
-        GPRReg gpr = info.gpr();
-        m_gprs.lock(gpr);
-        m_jit.jitAssertIsJSInt32(gpr);
-        returnFormat = DataFormatJSInteger;
-        return gpr;
-    }
-
-    case DataFormatInteger: {
-        GPRReg gpr = info.gpr();
-        m_gprs.lock(gpr);
-        m_jit.jitAssertIsInt32(gpr);
-        returnFormat = DataFormatInteger;
-        return gpr;
-    }
-    }
-
-    ASSERT_NOT_REACHED();
-    return InvalidGPRReg;
-}
-
-FPRReg JITCodeGenerator::fillDouble(NodeIndex nodeIndex)
-{
-    Node& node = m_jit.graph()[nodeIndex];
-    VirtualRegister virtualRegister = node.virtualRegister();
-    GenerationInfo& info = m_generationInfo[virtualRegister];
-
-    if (info.registerFormat() == DataFormatNone) {
-        GPRReg gpr = allocate();
-
-        if (node.isConstant()) {
-            if (isInt32Constant(nodeIndex)) {
-                // FIXME: should not be reachable?
-                m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
-                m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
-                info.fillInteger(gpr);
-                unlock(gpr);
-            } else if (isDoubleConstant(nodeIndex)) {
-                FPRReg fpr = fprAllocate();
-                m_jit.move(MacroAssembler::ImmPtr(reinterpret_cast<void*>(reinterpretDoubleToIntptr(valueOfDoubleConstant(nodeIndex)))), gpr);
-                m_jit.movePtrToDouble(gpr, fpr);
-                unlock(gpr);
-
-                m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
-                info.fillDouble(fpr);
-                return fpr;
-            } else {
-                // FIXME: should not be reachable?
-                ASSERT(isJSConstant(nodeIndex));
-                JSValue jsValue = valueOfJSConstant(nodeIndex);
-                m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
-                m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
-                info.fillJSValue(gpr, DataFormatJS);
-                unlock(gpr);
-            }
-        } else {
-            DataFormat spillFormat = info.spillFormat();
-            ASSERT(spillFormat & DataFormatJS);
-            m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
-            m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
-            info.fillJSValue(gpr, m_isSpeculative ? spillFormat : DataFormatJS);
-            unlock(gpr);
-        }
-    }
-
-    switch (info.registerFormat()) {
-    case DataFormatNone:
-        // Should have filled, above.
-    case DataFormatCell:
-    case DataFormatJSCell:
-        // Should only be calling this function if we know this operand to be numeric.
-        ASSERT_NOT_REACHED();
-
-    case DataFormatJS: {
-        GPRReg jsValueGpr = info.gpr();
-        m_gprs.lock(jsValueGpr);
-        FPRReg fpr = fprAllocate();
-        GPRReg tempGpr = allocate(); // FIXME: can we skip this allocation on the last use of the virtual register?
-
-        JITCompiler::Jump isInteger = m_jit.branchPtr(MacroAssembler::AboveOrEqual, jsValueGpr, GPRInfo::tagTypeNumberRegister);
-
-        m_jit.jitAssertIsJSDouble(jsValueGpr);
-
-        // First, if we get here we have a double encoded as a JSValue
-        m_jit.move(jsValueGpr, tempGpr);
-        m_jit.addPtr(GPRInfo::tagTypeNumberRegister, tempGpr);
-        m_jit.movePtrToDouble(tempGpr, fpr);
-        JITCompiler::Jump hasUnboxedDouble = m_jit.jump();
-
-        // Finally, handle integers.
-        isInteger.link(&m_jit);
-        m_jit.convertInt32ToDouble(jsValueGpr, fpr);
-        hasUnboxedDouble.link(&m_jit);
-
-        m_gprs.release(jsValueGpr);
-        m_gprs.unlock(jsValueGpr);
-        m_gprs.unlock(tempGpr);
-        m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
-        info.fillDouble(fpr);
-        return fpr;
-    }
-
-    case DataFormatJSInteger:
-    case DataFormatInteger: {
-        FPRReg fpr = fprAllocate();
-        GPRReg gpr = info.gpr();
-        m_gprs.lock(gpr);
-
-        m_jit.convertInt32ToDouble(gpr, fpr);
-
-        m_gprs.release(gpr);
-        m_gprs.unlock(gpr);
-        m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
-        info.fillDouble(fpr);
-        return fpr;
-    }
-
-    // Unbox the double
-    case DataFormatJSDouble: {
-        GPRReg gpr = info.gpr();
-        FPRReg fpr = unboxDouble(gpr);
-
-        m_gprs.release(gpr);
-        m_fprs.retain(fpr, virtualRegister, SpillOrderDouble);
-
-        info.fillDouble(fpr);
-        return fpr;
-    }
-
-    case DataFormatDouble: {
-        FPRReg fpr = info.fpr();
-        m_fprs.lock(fpr);
-        return fpr;
-    }
-    }
-
-    ASSERT_NOT_REACHED();
-    return InvalidFPRReg;
-}
-
-GPRReg JITCodeGenerator::fillJSValue(NodeIndex nodeIndex)
-{
-    Node& node = m_jit.graph()[nodeIndex];
-    VirtualRegister virtualRegister = node.virtualRegister();
-    GenerationInfo& info = m_generationInfo[virtualRegister];
-
-    switch (info.registerFormat()) {
-    case DataFormatNone: {
-        GPRReg gpr = allocate();
-
-        if (node.isConstant()) {
-            if (isInt32Constant(nodeIndex)) {
-                info.fillJSValue(gpr, DataFormatJSInteger);
-                JSValue jsValue = jsNumber(valueOfInt32Constant(nodeIndex));
-                m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
-            } else if (isDoubleConstant(nodeIndex)) {
-                info.fillJSValue(gpr, DataFormatJSDouble);
-                JSValue jsValue(JSValue::EncodeAsDouble, valueOfDoubleConstant(nodeIndex));
-                m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
-            } else {
-                ASSERT(isJSConstant(nodeIndex));
-                JSValue jsValue = valueOfJSConstant(nodeIndex);
-                m_jit.move(MacroAssembler::ImmPtr(JSValue::encode(jsValue)), gpr);
-                info.fillJSValue(gpr, DataFormatJS);
-            }
-
-            m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
-        } else {
-            DataFormat spillFormat = info.spillFormat();
-            ASSERT(spillFormat & DataFormatJS);
-            m_gprs.retain(gpr, virtualRegister, SpillOrderSpilled);
-            m_jit.loadPtr(JITCompiler::addressFor(virtualRegister), gpr);
-            info.fillJSValue(gpr, m_isSpeculative ? spillFormat : DataFormatJS);
-        }
-        return gpr;
-    }
-
-    case DataFormatInteger: {
-        GPRReg gpr = info.gpr();
-        // If the register has already been locked we need to take a copy.
-        // If not, we'll zero extend in place, so mark on the info that this is now type DataFormatInteger, not DataFormatJSInteger.
-        if (m_gprs.isLocked(gpr)) {
-            GPRReg result = allocate();
-            m_jit.orPtr(GPRInfo::tagTypeNumberRegister, gpr, result);
-            return result;
-        }
-        m_gprs.lock(gpr);
-        m_jit.orPtr(GPRInfo::tagTypeNumberRegister, gpr);
-        info.fillJSValue(gpr, DataFormatJSInteger);
-        return gpr;
-    }
-
-    case DataFormatDouble: {
-        FPRReg fpr = info.fpr();
-        GPRReg gpr = boxDouble(fpr);
-
-        // Update all info
-        info.fillJSValue(gpr, DataFormatJSDouble);
-        m_fprs.release(fpr);
-        m_gprs.retain(gpr, virtualRegister, SpillOrderJS);
-
-        return gpr;
-    }
-
-    case DataFormatCell:
-        // No retag required on JSVALUE64!
-    case DataFormatJS:
-    case DataFormatJSInteger:
-    case DataFormatJSDouble:
-    case DataFormatJSCell: {
-        GPRReg gpr = info.gpr();
-        m_gprs.lock(gpr);
-        return gpr;
-    }
-    }
-
-    ASSERT_NOT_REACHED();
-    return InvalidGPRReg;
-}
-
-void JITCodeGenerator::useChildren(Node& node)
-{
-    NodeIndex child1 = node.child1;
-    if (child1 == NoNode) {
-        ASSERT(node.child2 == NoNode && node.child3 == NoNode);
-        return;
-    }
-    use(child1);
-
-    NodeIndex child2 = node.child2;
-    if (child2 == NoNode) {
-        ASSERT(node.child3 == NoNode);
-        return;
-    }
-    use(child2);
-
-    NodeIndex child3 = node.child3;
-    if (child3 == NoNode)
-        return;
-    use(child3);
-}
-
-#ifndef NDEBUG
-static const char* dataFormatString(DataFormat format)
-{
-    // These values correspond to the DataFormat enum.
-    const char* strings[] = {
-        "[  ]",
-        "[ i]",
-        "[ d]",
-        "[ c]",
-        "Err!",
-        "Err!",
-        "Err!",
-        "Err!",
-        "[J ]",
-        "[Ji]",
-        "[Jd]",
-        "[Jc]",
-        "Err!",
-        "Err!",
-        "Err!",
-        "Err!",
-    };
-    return strings[format];
-}
-
-void JITCodeGenerator::dump(const char* label)
-{
-    if (label)
-        fprintf(stderr, "<%s>\n", label);
-
-    fprintf(stderr, "  gprs:\n");
-    m_gprs.dump();
-    fprintf(stderr, "  fprs:\n");
-    m_fprs.dump();
-    fprintf(stderr, "  VirtualRegisters:\n");
-    for (unsigned i = 0; i < m_generationInfo.size(); ++i) {
-        GenerationInfo& info = m_generationInfo[i];
-        if (info.alive())
-            fprintf(stderr, "    % 3d:%s%s", i, dataFormatString(info.registerFormat()), dataFormatString(info.spillFormat()));
-        else
-            fprintf(stderr, "    % 3d:[__][__]", i);
-        if (info.registerFormat() == DataFormatDouble)
-            fprintf(stderr, ":fpr%d\n", info.fpr());
-        else if (info.registerFormat() != DataFormatNone) {
-            ASSERT(info.gpr() != InvalidGPRReg);
-            fprintf(stderr, ":%s\n", GPRInfo::debugName(info.gpr()));
-        } else
-            fprintf(stderr, "\n");
-    }
-    if (label)
-        fprintf(stderr, "</%s>\n", label);
-}
-#endif
-
-
-#if DFG_CONSISTENCY_CHECK
-void JITCodeGenerator::checkConsistency()
-{
-    bool failed = false;
-
-    for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
-        if (iter.isLocked()) {
-            fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: gpr %s is locked.\n", iter.debugName());
-            failed = true;
-        }
-    }
-    for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
-        if (iter.isLocked()) {
-            fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: fpr %s is locked.\n", iter.debugName());
-            failed = true;
-        }
-    }
-
-    for (unsigned i = 0; i < m_generationInfo.size(); ++i) {
-        VirtualRegister virtualRegister = (VirtualRegister)i;
-        GenerationInfo& info = m_generationInfo[virtualRegister];
-        if (!info.alive())
-            continue;
-        switch (info.registerFormat()) {
-        case DataFormatNone:
-            break;
-        case DataFormatInteger:
-        case DataFormatCell:
-        case DataFormatJS:
-        case DataFormatJSInteger:
-        case DataFormatJSDouble:
-        case DataFormatJSCell: {
-            GPRReg gpr = info.gpr();
-            ASSERT(gpr != InvalidGPRReg);
-            if (m_gprs.name(gpr) != virtualRegister) {
-                fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for virtual register %d (gpr %s).\n", virtualRegister, GPRInfo::debugName(gpr));
-                failed = true;
-            }
-            break;
-        }
-        case DataFormatDouble: {
-            FPRReg fpr = info.fpr();
-            ASSERT(fpr != InvalidFPRReg);
-            if (m_fprs.name(fpr) != virtualRegister) {
-                fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for virtual register %d (fpr %s).\n", virtualRegister, FPRInfo::debugName(fpr));
-                failed = true;
-            }
-            break;
-        }
-        }
-    }
-
-    for (gpr_iterator iter = m_gprs.begin(); iter != m_gprs.end(); ++iter) {
-        VirtualRegister virtualRegister = iter.name();
-        if (virtualRegister == InvalidVirtualRegister)
-            continue;
-
-        GenerationInfo& info = m_generationInfo[virtualRegister];
-        if (iter.regID() != info.gpr()) {
-            fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for gpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
-            failed = true;
-        }
-    }
-
-    for (fpr_iterator iter = m_fprs.begin(); iter != m_fprs.end(); ++iter) {
-        VirtualRegister virtualRegister = iter.name();
-        if (virtualRegister == InvalidVirtualRegister)
-            continue;
-
-        GenerationInfo& info = m_generationInfo[virtualRegister];
-        if (iter.regID() != info.fpr()) {
-            fprintf(stderr, "DFG_CONSISTENCY_CHECK failed: name mismatch for fpr %s (virtual register %d).\n", iter.debugName(), virtualRegister);
-            failed = true;
-        }
-    }
-
-    if (failed) {
-        dump();
-        CRASH();
-    }
-}
-#endif
-
-GPRTemporary::GPRTemporary(JITCodeGenerator* jit)
-    : m_jit(jit)
-    , m_gpr(InvalidGPRReg)
-{
-    m_gpr = m_jit->allocate();
-}
-
-GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateIntegerOperand& op1)
-    : m_jit(jit)
-    , m_gpr(InvalidGPRReg)
-{
-    if (m_jit->canReuse(op1.index()))
-        m_gpr = m_jit->reuse(op1.gpr());
-    else
-        m_gpr = m_jit->allocate();
-}
-
-GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateIntegerOperand& op1, SpeculateIntegerOperand& op2)
-    : m_jit(jit)
-    , m_gpr(InvalidGPRReg)
-{
-    if (m_jit->canReuse(op1.index()))
-        m_gpr = m_jit->reuse(op1.gpr());
-    else if (m_jit->canReuse(op2.index()))
-        m_gpr = m_jit->reuse(op2.gpr());
-    else
-        m_gpr = m_jit->allocate();
-}
-
-GPRTemporary::GPRTemporary(JITCodeGenerator* jit, IntegerOperand& op1)
-    : m_jit(jit)
-    , m_gpr(InvalidGPRReg)
-{
-    if (m_jit->canReuse(op1.index()))
-        m_gpr = m_jit->reuse(op1.gpr());
-    else
-        m_gpr = m_jit->allocate();
-}
-
-GPRTemporary::GPRTemporary(JITCodeGenerator* jit, IntegerOperand& op1, IntegerOperand& op2)
-    : m_jit(jit)
-    , m_gpr(InvalidGPRReg)
-{
-    if (m_jit->canReuse(op1.index()))
-        m_gpr = m_jit->reuse(op1.gpr());
-    else if (m_jit->canReuse(op2.index()))
-        m_gpr = m_jit->reuse(op2.gpr());
-    else
-        m_gpr = m_jit->allocate();
-}
-
-GPRTemporary::GPRTemporary(JITCodeGenerator* jit, SpeculateCellOperand& op1)
-    : m_jit(jit)
-    , m_gpr(InvalidGPRReg)
-{
-    if (m_jit->canReuse(op1.index()))
-        m_gpr = m_jit->reuse(op1.gpr());
-    else
-        m_gpr = m_jit->allocate();
-}
-
-GPRTemporary::GPRTemporary(JITCodeGenerator* jit, JSValueOperand& op1)
-    : m_jit(jit)
-    , m_gpr(InvalidGPRReg)
-{
-    if (m_jit->canReuse(op1.index()))
-        m_gpr = m_jit->reuse(op1.gpr());
-    else
-        m_gpr = m_jit->allocate();
-}
-
-FPRTemporary::FPRTemporary(JITCodeGenerator* jit)
-    : m_jit(jit)
-    , m_fpr(InvalidFPRReg)
-{
-    m_fpr = m_jit->fprAllocate();
-}
-
-FPRTemporary::FPRTemporary(JITCodeGenerator* jit, DoubleOperand& op1)
-    : m_jit(jit)
-    , m_fpr(InvalidFPRReg)
-{
-    if (m_jit->canReuse(op1.index()))
-        m_fpr = m_jit->reuse(op1.fpr());
-    else
-        m_fpr = m_jit->fprAllocate();
-}
-
-FPRTemporary::FPRTemporary(JITCodeGenerator* jit, DoubleOperand& op1, DoubleOperand& op2)
-    : m_jit(jit)
-    , m_fpr(InvalidFPRReg)
-{
-    if (m_jit->canReuse(op1.index()))
-        m_fpr = m_jit->reuse(op1.fpr());
-    else if (m_jit->canReuse(op2.index()))
-        m_fpr = m_jit->reuse(op2.fpr());
-    else
-        m_fpr = m_jit->fprAllocate();
-}
-
-} } // namespace JSC::DFG
-
-#endif