summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecode/ValueRecovery.h
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-01-06 14:44:00 +0100
commit40736c5763bf61337c8c14e16d8587db021a87d4 (patch)
treeb17a9c00042ad89cb1308e2484491799aa14e9f8 /Source/JavaScriptCore/bytecode/ValueRecovery.h
downloadqtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Source/JavaScriptCore/bytecode/ValueRecovery.h')
-rw-r--r--Source/JavaScriptCore/bytecode/ValueRecovery.h337
1 files changed, 337 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/bytecode/ValueRecovery.h b/Source/JavaScriptCore/bytecode/ValueRecovery.h
new file mode 100644
index 000000000..356abe84f
--- /dev/null
+++ b/Source/JavaScriptCore/bytecode/ValueRecovery.h
@@ -0,0 +1,337 @@
+/*
+ * 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.
+ */
+
+#ifndef ValueRecovery_h
+#define ValueRecovery_h
+
+#include "DataFormat.h"
+#include "JSValue.h"
+#include "MacroAssembler.h"
+#include "VirtualRegister.h"
+#include <wtf/Platform.h>
+
+#ifndef NDEBUG
+#include <stdio.h>
+#endif
+
+namespace JSC {
+
+// Describes how to recover a given bytecode virtual register at a given
+// code point.
+enum ValueRecoveryTechnique {
+ // It's already in the register file at the right location.
+ AlreadyInRegisterFile,
+ // It's already in the register file but unboxed.
+ AlreadyInRegisterFileAsUnboxedInt32,
+ AlreadyInRegisterFileAsUnboxedCell,
+ AlreadyInRegisterFileAsUnboxedBoolean,
+ AlreadyInRegisterFileAsUnboxedDouble,
+ // It's in a register.
+ InGPR,
+ UnboxedInt32InGPR,
+ UnboxedBooleanInGPR,
+#if USE(JSVALUE32_64)
+ InPair,
+#endif
+ InFPR,
+ UInt32InGPR,
+ // It's in the register file, but at a different location.
+ DisplacedInRegisterFile,
+ // It's in the register file, at a different location, and it's unboxed.
+ Int32DisplacedInRegisterFile,
+ DoubleDisplacedInRegisterFile,
+ CellDisplacedInRegisterFile,
+ BooleanDisplacedInRegisterFile,
+ // It's a constant.
+ Constant,
+ // Don't know how to recover it.
+ DontKnow
+};
+
+class ValueRecovery {
+public:
+ ValueRecovery()
+ : m_technique(DontKnow)
+ {
+ }
+
+ static ValueRecovery alreadyInRegisterFile()
+ {
+ ValueRecovery result;
+ result.m_technique = AlreadyInRegisterFile;
+ return result;
+ }
+
+ static ValueRecovery alreadyInRegisterFileAsUnboxedInt32()
+ {
+ ValueRecovery result;
+ result.m_technique = AlreadyInRegisterFileAsUnboxedInt32;
+ return result;
+ }
+
+ static ValueRecovery alreadyInRegisterFileAsUnboxedCell()
+ {
+ ValueRecovery result;
+ result.m_technique = AlreadyInRegisterFileAsUnboxedCell;
+ return result;
+ }
+
+ static ValueRecovery alreadyInRegisterFileAsUnboxedBoolean()
+ {
+ ValueRecovery result;
+ result.m_technique = AlreadyInRegisterFileAsUnboxedBoolean;
+ return result;
+ }
+
+ static ValueRecovery alreadyInRegisterFileAsUnboxedDouble()
+ {
+ ValueRecovery result;
+ result.m_technique = AlreadyInRegisterFileAsUnboxedDouble;
+ return result;
+ }
+
+ static ValueRecovery inGPR(MacroAssembler::RegisterID gpr, DataFormat dataFormat)
+ {
+ ASSERT(dataFormat != DataFormatNone);
+#if USE(JSVALUE32_64)
+ ASSERT(dataFormat == DataFormatInteger || dataFormat == DataFormatCell || dataFormat == DataFormatBoolean);
+#endif
+ ValueRecovery result;
+ if (dataFormat == DataFormatInteger)
+ result.m_technique = UnboxedInt32InGPR;
+ else if (dataFormat == DataFormatBoolean)
+ result.m_technique = UnboxedBooleanInGPR;
+ else
+ result.m_technique = InGPR;
+ result.m_source.gpr = gpr;
+ return result;
+ }
+
+ static ValueRecovery uint32InGPR(MacroAssembler::RegisterID gpr)
+ {
+ ValueRecovery result;
+ result.m_technique = UInt32InGPR;
+ result.m_source.gpr = gpr;
+ return result;
+ }
+
+#if USE(JSVALUE32_64)
+ static ValueRecovery inPair(MacroAssembler::RegisterID tagGPR, MacroAssembler::RegisterID payloadGPR)
+ {
+ ValueRecovery result;
+ result.m_technique = InPair;
+ result.m_source.pair.tagGPR = tagGPR;
+ result.m_source.pair.payloadGPR = payloadGPR;
+ return result;
+ }
+#endif
+
+ static ValueRecovery inFPR(MacroAssembler::FPRegisterID fpr)
+ {
+ ValueRecovery result;
+ result.m_technique = InFPR;
+ result.m_source.fpr = fpr;
+ return result;
+ }
+
+ static ValueRecovery displacedInRegisterFile(VirtualRegister virtualReg, DataFormat dataFormat)
+ {
+ ValueRecovery result;
+ switch (dataFormat) {
+ case DataFormatInteger:
+ result.m_technique = Int32DisplacedInRegisterFile;
+ break;
+
+ case DataFormatDouble:
+ result.m_technique = DoubleDisplacedInRegisterFile;
+ break;
+
+ case DataFormatCell:
+ result.m_technique = CellDisplacedInRegisterFile;
+ break;
+
+ case DataFormatBoolean:
+ result.m_technique = BooleanDisplacedInRegisterFile;
+ break;
+
+ default:
+ ASSERT(dataFormat != DataFormatNone && dataFormat != DataFormatStorage);
+ result.m_technique = DisplacedInRegisterFile;
+ break;
+ }
+ result.m_source.virtualReg = virtualReg;
+ return result;
+ }
+
+ static ValueRecovery constant(JSValue value)
+ {
+ ValueRecovery result;
+ result.m_technique = Constant;
+ result.m_source.constant = JSValue::encode(value);
+ return result;
+ }
+
+ ValueRecoveryTechnique technique() const { return m_technique; }
+
+ bool isInRegisters() const
+ {
+ switch (m_technique) {
+ case InGPR:
+ case UnboxedInt32InGPR:
+ case UnboxedBooleanInGPR:
+#if USE(JSVALUE32_64)
+ case InPair:
+#endif
+ case InFPR:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ MacroAssembler::RegisterID gpr() const
+ {
+ ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR || m_technique == UInt32InGPR);
+ return m_source.gpr;
+ }
+
+#if USE(JSVALUE32_64)
+ MacroAssembler::RegisterID tagGPR() const
+ {
+ ASSERT(m_technique == InPair);
+ return m_source.pair.tagGPR;
+ }
+
+ MacroAssembler::RegisterID payloadGPR() const
+ {
+ ASSERT(m_technique == InPair);
+ return m_source.pair.payloadGPR;
+ }
+#endif
+
+ MacroAssembler::FPRegisterID fpr() const
+ {
+ ASSERT(m_technique == InFPR);
+ return m_source.fpr;
+ }
+
+ VirtualRegister virtualRegister() const
+ {
+ ASSERT(m_technique == DisplacedInRegisterFile || m_technique == Int32DisplacedInRegisterFile || m_technique == DoubleDisplacedInRegisterFile || m_technique == CellDisplacedInRegisterFile || m_technique == BooleanDisplacedInRegisterFile);
+ return m_source.virtualReg;
+ }
+
+ JSValue constant() const
+ {
+ ASSERT(m_technique == Constant);
+ return JSValue::decode(m_source.constant);
+ }
+
+#ifndef NDEBUG
+ void dump(FILE* out) const
+ {
+ switch (technique()) {
+ case AlreadyInRegisterFile:
+ fprintf(out, "-");
+ break;
+ case AlreadyInRegisterFileAsUnboxedInt32:
+ fprintf(out, "(int32)");
+ break;
+ case AlreadyInRegisterFileAsUnboxedCell:
+ fprintf(out, "(cell)");
+ break;
+ case AlreadyInRegisterFileAsUnboxedBoolean:
+ fprintf(out, "(bool)");
+ break;
+ case AlreadyInRegisterFileAsUnboxedDouble:
+ fprintf(out, "(double)");
+ break;
+ case InGPR:
+ fprintf(out, "%%r%d", gpr());
+ break;
+ case UnboxedInt32InGPR:
+ fprintf(out, "int32(%%r%d)", gpr());
+ break;
+ case UnboxedBooleanInGPR:
+ fprintf(out, "bool(%%r%d)", gpr());
+ break;
+ case UInt32InGPR:
+ fprintf(out, "uint32(%%r%d)", gpr());
+ break;
+ case InFPR:
+ fprintf(out, "%%fr%d", fpr());
+ break;
+#if USE(JSVALUE32_64)
+ case InPair:
+ fprintf(out, "pair(%%r%d, %%r%d)", tagGPR(), payloadGPR());
+ break;
+#endif
+ case DisplacedInRegisterFile:
+ fprintf(out, "*%d", virtualRegister());
+ break;
+ case Int32DisplacedInRegisterFile:
+ fprintf(out, "*int32(%d)", virtualRegister());
+ break;
+ case DoubleDisplacedInRegisterFile:
+ fprintf(out, "*double(%d)", virtualRegister());
+ break;
+ case CellDisplacedInRegisterFile:
+ fprintf(out, "*cell(%d)", virtualRegister());
+ break;
+ case BooleanDisplacedInRegisterFile:
+ fprintf(out, "*bool(%d)", virtualRegister());
+ break;
+ case Constant:
+ fprintf(out, "[%s]", constant().description());
+ break;
+ case DontKnow:
+ fprintf(out, "!");
+ break;
+ default:
+ fprintf(out, "?%d", technique());
+ break;
+ }
+ }
+#endif
+
+private:
+ ValueRecoveryTechnique m_technique;
+ union {
+ MacroAssembler::RegisterID gpr;
+ MacroAssembler::FPRegisterID fpr;
+#if USE(JSVALUE32_64)
+ struct {
+ MacroAssembler::RegisterID tagGPR;
+ MacroAssembler::RegisterID payloadGPR;
+ } pair;
+#endif
+ VirtualRegister virtualReg;
+ EncodedJSValue constant;
+ } m_source;
+};
+
+} // namespace JSC
+
+#endif // ValueRecovery_h