Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (99143 => 99144)
--- trunk/Source/_javascript_Core/ChangeLog 2011-11-03 06:46:45 UTC (rev 99143)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-11-03 06:55:29 UTC (rev 99144)
@@ -1,3 +1,46 @@
+2011-11-02 Filip Pizlo <[email protected]>
+
+ ValueRecovery should be moved out of the DFG JIT
+ https://bugs.webkit.org/show_bug.cgi?id=71439
+
+ Reviewed by Oliver Hunt.
+
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * bytecode/DataFormat.h: Added.
+ (JSC::dataFormatToString):
+ (JSC::needDataFormatConversion):
+ (JSC::isJSFormat):
+ (JSC::isJSInteger):
+ (JSC::isJSDouble):
+ (JSC::isJSCell):
+ (JSC::isJSBoolean):
+ * bytecode/ValueRecovery.h: Added.
+ (JSC::ValueRecovery::ValueRecovery):
+ (JSC::ValueRecovery::alreadyInRegisterFile):
+ (JSC::ValueRecovery::alreadyInRegisterFileAsUnboxedInt32):
+ (JSC::ValueRecovery::alreadyInRegisterFileAsUnboxedCell):
+ (JSC::ValueRecovery::alreadyInRegisterFileAsUnboxedBoolean):
+ (JSC::ValueRecovery::inGPR):
+ (JSC::ValueRecovery::inPair):
+ (JSC::ValueRecovery::inFPR):
+ (JSC::ValueRecovery::displacedInRegisterFile):
+ (JSC::ValueRecovery::constant):
+ (JSC::ValueRecovery::technique):
+ (JSC::ValueRecovery::isInRegisters):
+ (JSC::ValueRecovery::gpr):
+ (JSC::ValueRecovery::tagGPR):
+ (JSC::ValueRecovery::payloadGPR):
+ (JSC::ValueRecovery::fpr):
+ (JSC::ValueRecovery::virtualRegister):
+ (JSC::ValueRecovery::dump):
+ * bytecode/VirtualRegister.h: Added.
+ * dfg/DFGGenerationInfo.h:
+ (JSC::DFG::GenerationInfo::isJSFormat):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::ValueSource::dump):
+ * dfg/DFGSpeculativeJIT.h:
+ * dfg/DFGVariableAccessData.h:
+
2011-11-02 Sam Weinig <[email protected]>
Object.getOwnPropertyDescriptor() does not retrieve the getter/setter from a property on the window that has been overridden with a getter/setter
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (99143 => 99144)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2011-11-03 06:46:45 UTC (rev 99143)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2011-11-03 06:55:29 UTC (rev 99144)
@@ -50,6 +50,9 @@
0BF28A2911A33DC300638F84 /* SizeLimits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0BF28A2811A33DC300638F84 /* SizeLimits.cpp */; };
0F16D726142C39C000CF784A /* BitVector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F16D724142C39A200CF784A /* BitVector.cpp */; };
0F242DA713F3B1E8007ADD4C /* WeakReferenceHarvester.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A451460CBAB00131F8F /* ValueRecovery.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A461460CBAB00131F8F /* VirtualRegister.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F426A4A1460CD6B00131F8F /* DataFormat.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F620174143FCD330068B77C /* DFGVariableAccessData.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620172143FCD2F0068B77C /* DFGVariableAccessData.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F620175143FCD370068B77C /* DFGOperands.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620171143FCD2F0068B77C /* DFGOperands.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F620176143FCD3B0068B77C /* DFGBasicBlock.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F620170143FCD2F0068B77C /* DFGBasicBlock.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -810,6 +813,9 @@
0BF28A2811A33DC300638F84 /* SizeLimits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SizeLimits.cpp; sourceTree = "<group>"; };
0F16D724142C39A200CF784A /* BitVector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BitVector.cpp; sourceTree = "<group>"; };
0F242DA513F3B1BB007ADD4C /* WeakReferenceHarvester.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakReferenceHarvester.h; sourceTree = "<group>"; };
+ 0F426A451460CBAB00131F8F /* ValueRecovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueRecovery.h; sourceTree = "<group>"; };
+ 0F426A461460CBAB00131F8F /* VirtualRegister.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VirtualRegister.h; sourceTree = "<group>"; };
+ 0F426A4A1460CD6B00131F8F /* DataFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DataFormat.h; sourceTree = "<group>"; };
0F62016D143FCD2F0068B77C /* DFGAbstractState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGAbstractState.cpp; path = dfg/DFGAbstractState.cpp; sourceTree = "<group>"; };
0F62016E143FCD2F0068B77C /* DFGAbstractState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAbstractState.h; path = dfg/DFGAbstractState.h; sourceTree = "<group>"; };
0F62016F143FCD2F0068B77C /* DFGAbstractValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGAbstractValue.h; path = dfg/DFGAbstractValue.h; sourceTree = "<group>"; };
@@ -2390,6 +2396,9 @@
969A078F0ED1D3AE00F1F681 /* bytecode */ = {
isa = PBXGroup;
children = (
+ 0F426A4A1460CD6B00131F8F /* DataFormat.h */,
+ 0F426A451460CBAB00131F8F /* ValueRecovery.h */,
+ 0F426A461460CBAB00131F8F /* VirtualRegister.h */,
0FBD7E671447998F00481315 /* CodeOrigin.h */,
0FD82E8E14207A5100179C94 /* ValueProfile.cpp */,
0FD82E84141F3FDA00179C94 /* PredictedType.cpp */,
@@ -2885,6 +2894,9 @@
0F620178143FCD440068B77C /* DFGAbstractState.h in Headers */,
0FBD7E691447999600481315 /* CodeOrigin.h in Headers */,
65303D641447B9E100D3F904 /* ParserTokens.h in Headers */,
+ 0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */,
+ 0F426A491460CBB700131F8F /* VirtualRegister.h in Headers */,
+ 0F426A4B1460CD6E00131F8F /* DataFormat.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Added: trunk/Source/_javascript_Core/bytecode/DataFormat.h (0 => 99144)
--- trunk/Source/_javascript_Core/bytecode/DataFormat.h (rev 0)
+++ trunk/Source/_javascript_Core/bytecode/DataFormat.h 2011-11-03 06:55:29 UTC (rev 99144)
@@ -0,0 +1,181 @@
+/*
+ * 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 DataFormat_h
+#define DataFormat_h
+
+#include <wtf/Assertions.h>
+
+namespace JSC {
+
+// === DataFormat ===
+//
+// This enum tracks the current representation in which a value is being held.
+// Values may be unboxed primitives (int32, double, or cell), or boxed as a JSValue.
+// For boxed values, we may know the type of boxing that has taken place.
+// (May also need bool, array, object, string types!)
+enum DataFormat {
+ DataFormatNone = 0,
+ DataFormatInteger = 1,
+ DataFormatDouble = 2,
+ DataFormatBoolean = 3,
+ DataFormatCell = 4,
+ DataFormatStorage = 5,
+ DataFormatJS = 8,
+ DataFormatJSInteger = DataFormatJS | DataFormatInteger,
+ DataFormatJSDouble = DataFormatJS | DataFormatDouble,
+ DataFormatJSCell = DataFormatJS | DataFormatCell,
+ DataFormatJSBoolean = DataFormatJS | DataFormatBoolean
+};
+
+#ifndef NDEBUG
+inline const char* dataFormatToString(DataFormat dataFormat)
+{
+ switch (dataFormat) {
+ case DataFormatNone:
+ return "None";
+ case DataFormatInteger:
+ return "Integer";
+ case DataFormatDouble:
+ return "Double";
+ case DataFormatCell:
+ return "Cell";
+ case DataFormatBoolean:
+ return "Boolean";
+ case DataFormatStorage:
+ return "Storage";
+ case DataFormatJS:
+ return "JS";
+ case DataFormatJSInteger:
+ return "JSInteger";
+ case DataFormatJSDouble:
+ return "JSDouble";
+ case DataFormatJSCell:
+ return "JSCell";
+ case DataFormatJSBoolean:
+ return "JSBoolean";
+ default:
+ return "Unknown";
+ }
+}
+#endif
+
+#if USE(JSVALUE64)
+inline bool needDataFormatConversion(DataFormat from, DataFormat to)
+{
+ ASSERT(from != DataFormatNone);
+ ASSERT(to != DataFormatNone);
+ switch (from) {
+ case DataFormatInteger:
+ case DataFormatDouble:
+ return to != from;
+ case DataFormatCell:
+ case DataFormatJS:
+ case DataFormatJSInteger:
+ case DataFormatJSDouble:
+ case DataFormatJSCell:
+ case DataFormatJSBoolean:
+ switch (to) {
+ case DataFormatInteger:
+ case DataFormatDouble:
+ return true;
+ case DataFormatCell:
+ case DataFormatJS:
+ case DataFormatJSInteger:
+ case DataFormatJSDouble:
+ case DataFormatJSCell:
+ case DataFormatJSBoolean:
+ return false;
+ default:
+ // This captures DataFormatBoolean, which is currently unused.
+ ASSERT_NOT_REACHED();
+ }
+ case DataFormatStorage:
+ ASSERT(to == DataFormatStorage);
+ return false;
+ default:
+ // This captures DataFormatBoolean, which is currently unused.
+ ASSERT_NOT_REACHED();
+ }
+ return true;
+}
+
+#elif USE(JSVALUE32_64)
+inline bool needDataFormatConversion(DataFormat from, DataFormat to)
+{
+ ASSERT(from != DataFormatNone);
+ ASSERT(to != DataFormatNone);
+ switch (from) {
+ case DataFormatInteger:
+ case DataFormatCell:
+ case DataFormatBoolean:
+ return ((to & DataFormatJS) || to == DataFormatDouble);
+ case DataFormatDouble:
+ case DataFormatJSDouble:
+ return (to != DataFormatDouble && to != DataFormatJSDouble);
+ case DataFormatJS:
+ case DataFormatJSInteger:
+ case DataFormatJSCell:
+ case DataFormatJSBoolean:
+ return (!(to & DataFormatJS) || to == DataFormatJSDouble);
+ case DataFormatStorage:
+ ASSERT(to == DataFormatStorage);
+ return false;
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ return true;
+}
+#endif
+
+inline bool isJSFormat(DataFormat format, DataFormat expectedFormat)
+{
+ ASSERT(expectedFormat & DataFormatJS);
+ return (format | DataFormatJS) == expectedFormat;
+}
+
+inline bool isJSInteger(DataFormat format)
+{
+ return isJSFormat(format, DataFormatJSInteger);
+}
+
+inline bool isJSDouble(DataFormat format)
+{
+ return isJSFormat(format, DataFormatJSDouble);
+}
+
+inline bool isJSCell(DataFormat format)
+{
+ return isJSFormat(format, DataFormatJSCell);
+}
+
+inline bool isJSBoolean(DataFormat format)
+{
+ return isJSFormat(format, DataFormatJSBoolean);
+}
+
+}
+
+#endif // DataFormat_h
Added: trunk/Source/_javascript_Core/bytecode/ValueRecovery.h (0 => 99144)
--- trunk/Source/_javascript_Core/bytecode/ValueRecovery.h (rev 0)
+++ trunk/Source/_javascript_Core/bytecode/ValueRecovery.h 2011-11-03 06:55:29 UTC (rev 99144)
@@ -0,0 +1,294 @@
+/*
+ * 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>
+
+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,
+ // It's in a register.
+ InGPR,
+ UnboxedInt32InGPR,
+ UnboxedBooleanInGPR,
+#if USE(JSVALUE32_64)
+ InPair,
+#endif
+ InFPR,
+ // 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,
+ // 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 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;
+ }
+
+#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;
+
+ 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);
+ 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);
+ 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 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 InFPR:
+ fprintf(out, "%%r%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 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
Added: trunk/Source/_javascript_Core/bytecode/VirtualRegister.h (0 => 99144)
--- trunk/Source/_javascript_Core/bytecode/VirtualRegister.h (rev 0)
+++ trunk/Source/_javascript_Core/bytecode/VirtualRegister.h 2011-11-03 06:55:29 UTC (rev 99144)
@@ -0,0 +1,40 @@
+/*
+ * 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 VirtualRegister_h
+#define VirtualRegister_h
+
+#include <wtf/Platform.h>
+
+namespace JSC {
+
+// Type for a virtual register number (spill location).
+// Using an enum to make this type-checked at compile time, to avert programmer errors.
+enum VirtualRegister { InvalidVirtualRegister = -1 };
+COMPILE_ASSERT(sizeof(VirtualRegister) == sizeof(int), VirtualRegister_is_32bit);
+
+} // namespace JSC
+
+#endif // VirtualRegister_h
Modified: trunk/Source/_javascript_Core/dfg/DFGGenerationInfo.h (99143 => 99144)
--- trunk/Source/_javascript_Core/dfg/DFGGenerationInfo.h 2011-11-03 06:46:45 UTC (rev 99143)
+++ trunk/Source/_javascript_Core/dfg/DFGGenerationInfo.h 2011-11-03 06:55:29 UTC (rev 99144)
@@ -28,156 +28,11 @@
#if ENABLE(DFG_JIT)
+#include "DataFormat.h"
#include <dfg/DFGJITCompiler.h>
namespace JSC { namespace DFG {
-// === DataFormat ===
-//
-// This enum tracks the current representation in which a value is being held.
-// Values may be unboxed primitives (int32, double, or cell), or boxed as a JSValue.
-// For boxed values, we may know the type of boxing that has taken place.
-// (May also need bool, array, object, string types!)
-enum DataFormat {
- DataFormatNone = 0,
- DataFormatInteger = 1,
- DataFormatDouble = 2,
- DataFormatBoolean = 3,
- DataFormatCell = 4,
- DataFormatStorage = 5,
- DataFormatJS = 8,
- DataFormatJSInteger = DataFormatJS | DataFormatInteger,
- DataFormatJSDouble = DataFormatJS | DataFormatDouble,
- DataFormatJSCell = DataFormatJS | DataFormatCell,
- DataFormatJSBoolean = DataFormatJS | DataFormatBoolean
-};
-
-#ifndef NDEBUG
-inline const char* dataFormatToString(DataFormat dataFormat)
-{
- switch (dataFormat) {
- case DataFormatNone:
- return "None";
- case DataFormatInteger:
- return "Integer";
- case DataFormatDouble:
- return "Double";
- case DataFormatCell:
- return "Cell";
- case DataFormatBoolean:
- return "Boolean";
- case DataFormatStorage:
- return "Storage";
- case DataFormatJS:
- return "JS";
- case DataFormatJSInteger:
- return "JSInteger";
- case DataFormatJSDouble:
- return "JSDouble";
- case DataFormatJSCell:
- return "JSCell";
- case DataFormatJSBoolean:
- return "JSBoolean";
- default:
- return "Unknown";
- }
-}
-#endif
-
-#if USE(JSVALUE64)
-inline bool needDataFormatConversion(DataFormat from, DataFormat to)
-{
- ASSERT(from != DataFormatNone);
- ASSERT(to != DataFormatNone);
- switch (from) {
- case DataFormatInteger:
- case DataFormatDouble:
- return to != from;
- case DataFormatCell:
- case DataFormatJS:
- case DataFormatJSInteger:
- case DataFormatJSDouble:
- case DataFormatJSCell:
- case DataFormatJSBoolean:
- switch (to) {
- case DataFormatInteger:
- case DataFormatDouble:
- return true;
- case DataFormatCell:
- case DataFormatJS:
- case DataFormatJSInteger:
- case DataFormatJSDouble:
- case DataFormatJSCell:
- case DataFormatJSBoolean:
- return false;
- default:
- // This captures DataFormatBoolean, which is currently unused.
- ASSERT_NOT_REACHED();
- }
- case DataFormatStorage:
- ASSERT(to == DataFormatStorage);
- return false;
- default:
- // This captures DataFormatBoolean, which is currently unused.
- ASSERT_NOT_REACHED();
- }
- return true;
-}
-
-#elif USE(JSVALUE32_64)
-inline bool needDataFormatConversion(DataFormat from, DataFormat to)
-{
- ASSERT(from != DataFormatNone);
- ASSERT(to != DataFormatNone);
- switch (from) {
- case DataFormatInteger:
- case DataFormatCell:
- case DataFormatBoolean:
- return ((to & DataFormatJS) || to == DataFormatDouble);
- case DataFormatDouble:
- case DataFormatJSDouble:
- return (to != DataFormatDouble && to != DataFormatJSDouble);
- case DataFormatJS:
- case DataFormatJSInteger:
- case DataFormatJSCell:
- case DataFormatJSBoolean:
- return (!(to & DataFormatJS) || to == DataFormatJSDouble);
- case DataFormatStorage:
- ASSERT(to == DataFormatStorage);
- return false;
- default:
- ASSERT_NOT_REACHED();
- }
- return true;
-}
-#endif
-
-inline bool isJSFormat(DataFormat format, DataFormat expectedFormat)
-{
- ASSERT(expectedFormat & DataFormatJS);
- return (format | DataFormatJS) == expectedFormat;
-}
-
-inline bool isJSInteger(DataFormat format)
-{
- return isJSFormat(format, DataFormatJSInteger);
-}
-
-inline bool isJSDouble(DataFormat format)
-{
- return isJSFormat(format, DataFormatJSDouble);
-}
-
-inline bool isJSCell(DataFormat format)
-{
- return isJSFormat(format, DataFormatJSCell);
-}
-
-inline bool isJSBoolean(DataFormat format)
-{
- return isJSFormat(format, DataFormatJSBoolean);
-}
-
// === GenerationInfo ===
//
// This class is used to track the current status of a live values during code generation.
@@ -306,7 +161,7 @@
bool isJSFormat(DataFormat expectedFormat)
{
- return DFG::isJSFormat(registerFormat(), expectedFormat) || DFG::isJSFormat(spillFormat(), expectedFormat);
+ return JSC::isJSFormat(registerFormat(), expectedFormat) || JSC::isJSFormat(spillFormat(), expectedFormat);
}
bool isJSInteger()
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (99143 => 99144)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-11-03 06:46:45 UTC (rev 99143)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-11-03 06:55:29 UTC (rev 99144)
@@ -60,60 +60,7 @@
break;
}
}
-
-void ValueRecovery::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 InGPR:
- fprintf(out, "%%%s", GPRInfo::debugName(gpr()));
- break;
- case UnboxedInt32InGPR:
- fprintf(out, "int32(%%%s)", GPRInfo::debugName(gpr()));
- break;
- case UnboxedBooleanInGPR:
- fprintf(out, "bool(%%%s)", GPRInfo::debugName(gpr()));
- break;
- case InFPR:
- fprintf(out, "%%%s", FPRInfo::debugName(fpr()));
- break;
-#if USE(JSVALUE32_64)
- case InPair:
- fprintf(out, "pair(%%%s, %%%s)", GPRInfo::debugName(tagGPR()), GPRInfo::debugName(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 Constant:
- fprintf(out, "[%s]", constant().description());
- break;
- case DontKnow:
- fprintf(out, "!");
- break;
- default:
- fprintf(out, "?%d", technique());
- break;
- }
-}
-#endif
OSRExit::OSRExit(JSValueSource jsValueSource, ValueProfile* valueProfile, MacroAssembler::Jump check, SpeculativeJIT* jit, unsigned recoveryIndex)
: m_jsValueSource(jsValueSource)
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (99143 => 99144)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-11-03 06:46:45 UTC (rev 99143)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-11-03 06:55:29 UTC (rev 99144)
@@ -28,6 +28,7 @@
#if ENABLE(DFG_JIT)
+#include "ValueRecovery.h"
#include <dfg/DFGAbstractState.h>
#include <dfg/DFGJITCodeGenerator.h>
@@ -145,194 +146,6 @@
NodeIndex m_nodeIndex;
};
-// 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,
- // It's in a register.
- InGPR,
- UnboxedInt32InGPR,
- UnboxedBooleanInGPR,
-#if USE(JSVALUE32_64)
- InPair,
-#endif
- InFPR,
- // 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,
- // 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 inGPR(GPRReg 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;
- }
-
-#if USE(JSVALUE32_64)
- static ValueRecovery inPair(GPRReg tagGPR, GPRReg 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(FPRReg 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;
-
- 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; }
-
- GPRReg gpr() const
- {
- ASSERT(m_technique == InGPR || m_technique == UnboxedInt32InGPR || m_technique == UnboxedBooleanInGPR);
- return m_source.gpr;
- }
-
-#if USE(JSVALUE32_64)
- GPRReg tagGPR() const
- {
- ASSERT(m_technique == InPair);
- return m_source.pair.tagGPR;
- }
-
- GPRReg payloadGPR() const
- {
- ASSERT(m_technique == InPair);
- return m_source.pair.payloadGPR;
- }
-#endif
-
- FPRReg fpr() const
- {
- ASSERT(m_technique == InFPR);
- return m_source.fpr;
- }
-
- VirtualRegister virtualRegister() const
- {
- ASSERT(m_technique == DisplacedInRegisterFile || m_technique == Int32DisplacedInRegisterFile || m_technique == DoubleDisplacedInRegisterFile);
- return m_source.virtualReg;
- }
-
- JSValue constant() const
- {
- ASSERT(m_technique == Constant);
- return JSValue::decode(m_source.constant);
- }
-
-#ifndef NDEBUG
- void dump(FILE* out) const;
-#endif
-
-private:
- ValueRecoveryTechnique m_technique;
- union {
- GPRReg gpr;
- FPRReg fpr;
-#if USE(JSVALUE32_64)
- struct {
- GPRReg tagGPR;
- GPRReg payloadGPR;
- } pair;
-#endif
- VirtualRegister virtualReg;
- EncodedJSValue constant;
- } m_source;
-};
-
// === OSRExit ===
//
// This structure describes how to exit the speculative path by
Modified: trunk/Source/_javascript_Core/dfg/DFGVariableAccessData.h (99143 => 99144)
--- trunk/Source/_javascript_Core/dfg/DFGVariableAccessData.h 2011-11-03 06:46:45 UTC (rev 99143)
+++ trunk/Source/_javascript_Core/dfg/DFGVariableAccessData.h 2011-11-03 06:55:29 UTC (rev 99144)
@@ -26,19 +26,13 @@
#ifndef DFGVariableAccessData_h
#define DFGVariableAccessData_h
+#include "PredictedType.h"
+#include "VirtualRegister.h"
#include <wtf/Platform.h>
-
-#if ENABLE(DFG_JIT)
-
#include <wtf/UnionFind.h>
namespace JSC { namespace DFG {
-// Type for a virtual register number (spill location).
-// Using an enum to make this type-checked at compile time, to avert programmer errors.
-enum VirtualRegister { InvalidVirtualRegister = -1 };
-COMPILE_ASSERT(sizeof(VirtualRegister) == sizeof(int), VirtualRegister_is_32bit);
-
class VariableAccessData: public UnionFind<VariableAccessData> {
public:
VariableAccessData()
@@ -86,6 +80,4 @@
} } // namespace JSC::DFG
-#endif // ENABLE(DFG_JIT)
-
#endif // DFGVariableAccessData_h