B3::Stackmap should be a superclass of B3::PatchpointValue and B3::CheckValue rather...
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Nov 2015 00:13:27 +0000 (00:13 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 4 Nov 2015 00:13:27 +0000 (00:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=150831

Rubber stamped by Benjamin Poulain.

Previously, Stackmap was a value that PatchpointValue and CheckValue would hold as a field.
We'd have convenient ways of getting this field, like via Value::stackmap(). But this was a
bit ridiculous, since Stackmap is logically just a common supertype for Patchpointvalue and
CheckValue. This patch makes this reality by replacing Stackmap with StackmapValue. This makes
the code a lot more reasonable.

I also needed to make dumping a bit more customizable, so I changed dumpMeta() to take a
CommaPrinter&. This gives subclasses better control over whether or not to emit a comma. Also
it's now possible for subclasses of Value to customize how children are printed. StackmapValue
uses this to print the children and their reps together like:

    Int32 @2 = Patchpoint(@0:SomeRegister, @1:SomeRegister, generator = 0x1107ec010, clobbered = [], usedRegisters = [], ExitsSideways|ControlDependent|Writes:Top|Reads:Top)

This has no behavior change, it's just a big refactoring. You can see how much simpler this
makes things by looking at the testSimplePatchpoint() test.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* b3/B3ArgumentRegValue.cpp:
(JSC::B3::ArgumentRegValue::~ArgumentRegValue):
(JSC::B3::ArgumentRegValue::dumpMeta):
* b3/B3ArgumentRegValue.h:
* b3/B3CheckSpecial.cpp:
(JSC::B3::CheckSpecial::generate):
* b3/B3CheckValue.cpp:
(JSC::B3::CheckValue::~CheckValue):
(JSC::B3::CheckValue::CheckValue):
(JSC::B3::CheckValue::dumpMeta): Deleted.
* b3/B3CheckValue.h:
(JSC::B3::CheckValue::accepts):
* b3/B3Const32Value.cpp:
(JSC::B3::Const32Value::notEqualConstant):
(JSC::B3::Const32Value::dumpMeta):
* b3/B3Const32Value.h:
* b3/B3Const64Value.cpp:
(JSC::B3::Const64Value::notEqualConstant):
(JSC::B3::Const64Value::dumpMeta):
* b3/B3Const64Value.h:
* b3/B3ConstDoubleValue.cpp:
(JSC::B3::ConstDoubleValue::notEqualConstant):
(JSC::B3::ConstDoubleValue::dumpMeta):
* b3/B3ConstDoubleValue.h:
* b3/B3ConstrainedValue.cpp: Added.
(JSC::B3::ConstrainedValue::dump):
* b3/B3ConstrainedValue.h: Added.
(JSC::B3::ConstrainedValue::ConstrainedValue):
(JSC::B3::ConstrainedValue::operator bool):
(JSC::B3::ConstrainedValue::value):
(JSC::B3::ConstrainedValue::rep):
* b3/B3ControlValue.cpp:
(JSC::B3::ControlValue::convertToJump):
(JSC::B3::ControlValue::dumpMeta):
* b3/B3ControlValue.h:
* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::tryPatchpoint):
* b3/B3MemoryValue.cpp:
(JSC::B3::MemoryValue::accessByteSize):
(JSC::B3::MemoryValue::dumpMeta):
* b3/B3MemoryValue.h:
* b3/B3PatchpointSpecial.cpp:
(JSC::B3::PatchpointSpecial::generate):
* b3/B3PatchpointValue.cpp:
(JSC::B3::PatchpointValue::~PatchpointValue):
(JSC::B3::PatchpointValue::PatchpointValue):
(JSC::B3::PatchpointValue::dumpMeta): Deleted.
* b3/B3PatchpointValue.h:
(JSC::B3::PatchpointValue::accepts):
* b3/B3StackSlotValue.cpp:
(JSC::B3::StackSlotValue::~StackSlotValue):
(JSC::B3::StackSlotValue::dumpMeta):
* b3/B3StackSlotValue.h:
* b3/B3Stackmap.cpp: Removed.
* b3/B3Stackmap.h: Removed.
* b3/B3StackmapSpecial.cpp:
(JSC::B3::StackmapSpecial::reportUsedRegisters):
(JSC::B3::StackmapSpecial::extraClobberedRegs):
(JSC::B3::StackmapSpecial::forEachArgImpl):
(JSC::B3::StackmapSpecial::isValidImpl):
(JSC::B3::StackmapSpecial::admitsStackImpl):
* b3/B3StackmapSpecial.h:
* b3/B3StackmapValue.cpp: Added.
(JSC::B3::StackmapValue::~StackmapValue):
(JSC::B3::StackmapValue::append):
(JSC::B3::StackmapValue::setConstrainedChild):
(JSC::B3::StackmapValue::setConstraint):
(JSC::B3::StackmapValue::dumpChildren):
(JSC::B3::StackmapValue::dumpMeta):
(JSC::B3::StackmapValue::StackmapValue):
* b3/B3StackmapValue.h: Added.
* b3/B3SwitchValue.cpp:
(JSC::B3::SwitchValue::appendCase):
(JSC::B3::SwitchValue::dumpMeta):
(JSC::B3::SwitchValue::SwitchValue):
* b3/B3SwitchValue.h:
* b3/B3UpsilonValue.cpp:
(JSC::B3::UpsilonValue::~UpsilonValue):
(JSC::B3::UpsilonValue::dumpMeta):
* b3/B3UpsilonValue.h:
* b3/B3Validate.cpp:
* b3/B3Value.cpp:
(JSC::B3::Value::dump):
(JSC::B3::Value::dumpChildren):
(JSC::B3::Value::deepDump):
(JSC::B3::Value::performSubstitution):
(JSC::B3::Value::dumpMeta):
* b3/B3Value.h:
* b3/B3ValueInlines.h:
(JSC::B3::Value::asNumber):
(JSC::B3::Value::stackmap): Deleted.
* b3/B3ValueRep.h:
(JSC::B3::ValueRep::kind):
(JSC::B3::ValueRep::operator==):
(JSC::B3::ValueRep::operator!=):
(JSC::B3::ValueRep::operator bool):
(JSC::B3::ValueRep::isAny):
* b3/air/AirInstInlines.h:
* b3/testb3.cpp:
(JSC::B3::testSimplePatchpoint):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@191993 268f45cc-cd09-0410-ab3c-d52691b4dbfc

42 files changed:
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/b3/B3ArgumentRegValue.cpp
Source/JavaScriptCore/b3/B3ArgumentRegValue.h
Source/JavaScriptCore/b3/B3CheckSpecial.cpp
Source/JavaScriptCore/b3/B3CheckValue.cpp
Source/JavaScriptCore/b3/B3CheckValue.h
Source/JavaScriptCore/b3/B3Const32Value.cpp
Source/JavaScriptCore/b3/B3Const32Value.h
Source/JavaScriptCore/b3/B3Const64Value.cpp
Source/JavaScriptCore/b3/B3Const64Value.h
Source/JavaScriptCore/b3/B3ConstDoubleValue.cpp
Source/JavaScriptCore/b3/B3ConstDoubleValue.h
Source/JavaScriptCore/b3/B3ConstrainedValue.cpp [moved from Source/JavaScriptCore/b3/B3Stackmap.cpp with 81% similarity]
Source/JavaScriptCore/b3/B3ConstrainedValue.h [new file with mode: 0644]
Source/JavaScriptCore/b3/B3ControlValue.cpp
Source/JavaScriptCore/b3/B3ControlValue.h
Source/JavaScriptCore/b3/B3LowerToAir.cpp
Source/JavaScriptCore/b3/B3MemoryValue.cpp
Source/JavaScriptCore/b3/B3MemoryValue.h
Source/JavaScriptCore/b3/B3PatchpointSpecial.cpp
Source/JavaScriptCore/b3/B3PatchpointValue.cpp
Source/JavaScriptCore/b3/B3PatchpointValue.h
Source/JavaScriptCore/b3/B3StackSlotValue.cpp
Source/JavaScriptCore/b3/B3StackSlotValue.h
Source/JavaScriptCore/b3/B3Stackmap.h [deleted file]
Source/JavaScriptCore/b3/B3StackmapSpecial.cpp
Source/JavaScriptCore/b3/B3StackmapSpecial.h
Source/JavaScriptCore/b3/B3StackmapValue.cpp [new file with mode: 0644]
Source/JavaScriptCore/b3/B3StackmapValue.h [new file with mode: 0644]
Source/JavaScriptCore/b3/B3SwitchValue.cpp
Source/JavaScriptCore/b3/B3SwitchValue.h
Source/JavaScriptCore/b3/B3UpsilonValue.cpp
Source/JavaScriptCore/b3/B3UpsilonValue.h
Source/JavaScriptCore/b3/B3Validate.cpp
Source/JavaScriptCore/b3/B3Value.cpp
Source/JavaScriptCore/b3/B3Value.h
Source/JavaScriptCore/b3/B3ValueInlines.h
Source/JavaScriptCore/b3/B3ValueRep.h
Source/JavaScriptCore/b3/air/AirInstInlines.h
Source/JavaScriptCore/b3/testb3.cpp

index 9642d69..8b6a500 100644 (file)
@@ -92,6 +92,7 @@ set(JavaScriptCore_SOURCES
     b3/B3BasicBlock.cpp
     b3/B3CheckSpecial.cpp
     b3/B3CheckValue.cpp
+    b3/B3ConstrainedValue.cpp
     b3/B3Common.cpp
     b3/B3Commutativity.cpp
     b3/B3Const32Value.cpp
@@ -112,8 +113,8 @@ set(JavaScriptCore_SOURCES
     b3/B3PhaseScope.cpp
     b3/B3Procedure.cpp
     b3/B3ReduceStrength.cpp
-    b3/B3Stackmap.cpp
     b3/B3StackmapSpecial.cpp
+    b3/B3StackmapValue.cpp
     b3/B3StackSlotKind.cpp
     b3/B3StackSlotValue.cpp
     b3/B3SwitchCase.cpp
index ced648e..7b06430 100644 (file)
@@ -1,3 +1,129 @@
+2015-11-03  Filip Pizlo  <fpizlo@apple.com>
+
+        B3::Stackmap should be a superclass of B3::PatchpointValue and B3::CheckValue rather than being one of their members
+        https://bugs.webkit.org/show_bug.cgi?id=150831
+
+        Rubber stamped by Benjamin Poulain.
+
+        Previously, Stackmap was a value that PatchpointValue and CheckValue would hold as a field.
+        We'd have convenient ways of getting this field, like via Value::stackmap(). But this was a
+        bit ridiculous, since Stackmap is logically just a common supertype for Patchpointvalue and
+        CheckValue. This patch makes this reality by replacing Stackmap with StackmapValue. This makes
+        the code a lot more reasonable.
+
+        I also needed to make dumping a bit more customizable, so I changed dumpMeta() to take a
+        CommaPrinter&. This gives subclasses better control over whether or not to emit a comma. Also
+        it's now possible for subclasses of Value to customize how children are printed. StackmapValue
+        uses this to print the children and their reps together like:
+
+            Int32 @2 = Patchpoint(@0:SomeRegister, @1:SomeRegister, generator = 0x1107ec010, clobbered = [], usedRegisters = [], ExitsSideways|ControlDependent|Writes:Top|Reads:Top)
+
+        This has no behavior change, it's just a big refactoring. You can see how much simpler this
+        makes things by looking at the testSimplePatchpoint() test.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * b3/B3ArgumentRegValue.cpp:
+        (JSC::B3::ArgumentRegValue::~ArgumentRegValue):
+        (JSC::B3::ArgumentRegValue::dumpMeta):
+        * b3/B3ArgumentRegValue.h:
+        * b3/B3CheckSpecial.cpp:
+        (JSC::B3::CheckSpecial::generate):
+        * b3/B3CheckValue.cpp:
+        (JSC::B3::CheckValue::~CheckValue):
+        (JSC::B3::CheckValue::CheckValue):
+        (JSC::B3::CheckValue::dumpMeta): Deleted.
+        * b3/B3CheckValue.h:
+        (JSC::B3::CheckValue::accepts):
+        * b3/B3Const32Value.cpp:
+        (JSC::B3::Const32Value::notEqualConstant):
+        (JSC::B3::Const32Value::dumpMeta):
+        * b3/B3Const32Value.h:
+        * b3/B3Const64Value.cpp:
+        (JSC::B3::Const64Value::notEqualConstant):
+        (JSC::B3::Const64Value::dumpMeta):
+        * b3/B3Const64Value.h:
+        * b3/B3ConstDoubleValue.cpp:
+        (JSC::B3::ConstDoubleValue::notEqualConstant):
+        (JSC::B3::ConstDoubleValue::dumpMeta):
+        * b3/B3ConstDoubleValue.h:
+        * b3/B3ConstrainedValue.cpp: Added.
+        (JSC::B3::ConstrainedValue::dump):
+        * b3/B3ConstrainedValue.h: Added.
+        (JSC::B3::ConstrainedValue::ConstrainedValue):
+        (JSC::B3::ConstrainedValue::operator bool):
+        (JSC::B3::ConstrainedValue::value):
+        (JSC::B3::ConstrainedValue::rep):
+        * b3/B3ControlValue.cpp:
+        (JSC::B3::ControlValue::convertToJump):
+        (JSC::B3::ControlValue::dumpMeta):
+        * b3/B3ControlValue.h:
+        * b3/B3LowerToAir.cpp:
+        (JSC::B3::Air::LowerToAir::tryPatchpoint):
+        * b3/B3MemoryValue.cpp:
+        (JSC::B3::MemoryValue::accessByteSize):
+        (JSC::B3::MemoryValue::dumpMeta):
+        * b3/B3MemoryValue.h:
+        * b3/B3PatchpointSpecial.cpp:
+        (JSC::B3::PatchpointSpecial::generate):
+        * b3/B3PatchpointValue.cpp:
+        (JSC::B3::PatchpointValue::~PatchpointValue):
+        (JSC::B3::PatchpointValue::PatchpointValue):
+        (JSC::B3::PatchpointValue::dumpMeta): Deleted.
+        * b3/B3PatchpointValue.h:
+        (JSC::B3::PatchpointValue::accepts):
+        * b3/B3StackSlotValue.cpp:
+        (JSC::B3::StackSlotValue::~StackSlotValue):
+        (JSC::B3::StackSlotValue::dumpMeta):
+        * b3/B3StackSlotValue.h:
+        * b3/B3Stackmap.cpp: Removed.
+        * b3/B3Stackmap.h: Removed.
+        * b3/B3StackmapSpecial.cpp:
+        (JSC::B3::StackmapSpecial::reportUsedRegisters):
+        (JSC::B3::StackmapSpecial::extraClobberedRegs):
+        (JSC::B3::StackmapSpecial::forEachArgImpl):
+        (JSC::B3::StackmapSpecial::isValidImpl):
+        (JSC::B3::StackmapSpecial::admitsStackImpl):
+        * b3/B3StackmapSpecial.h:
+        * b3/B3StackmapValue.cpp: Added.
+        (JSC::B3::StackmapValue::~StackmapValue):
+        (JSC::B3::StackmapValue::append):
+        (JSC::B3::StackmapValue::setConstrainedChild):
+        (JSC::B3::StackmapValue::setConstraint):
+        (JSC::B3::StackmapValue::dumpChildren):
+        (JSC::B3::StackmapValue::dumpMeta):
+        (JSC::B3::StackmapValue::StackmapValue):
+        * b3/B3StackmapValue.h: Added.
+        * b3/B3SwitchValue.cpp:
+        (JSC::B3::SwitchValue::appendCase):
+        (JSC::B3::SwitchValue::dumpMeta):
+        (JSC::B3::SwitchValue::SwitchValue):
+        * b3/B3SwitchValue.h:
+        * b3/B3UpsilonValue.cpp:
+        (JSC::B3::UpsilonValue::~UpsilonValue):
+        (JSC::B3::UpsilonValue::dumpMeta):
+        * b3/B3UpsilonValue.h:
+        * b3/B3Validate.cpp:
+        * b3/B3Value.cpp:
+        (JSC::B3::Value::dump):
+        (JSC::B3::Value::dumpChildren):
+        (JSC::B3::Value::deepDump):
+        (JSC::B3::Value::performSubstitution):
+        (JSC::B3::Value::dumpMeta):
+        * b3/B3Value.h:
+        * b3/B3ValueInlines.h:
+        (JSC::B3::Value::asNumber):
+        (JSC::B3::Value::stackmap): Deleted.
+        * b3/B3ValueRep.h:
+        (JSC::B3::ValueRep::kind):
+        (JSC::B3::ValueRep::operator==):
+        (JSC::B3::ValueRep::operator!=):
+        (JSC::B3::ValueRep::operator bool):
+        (JSC::B3::ValueRep::isAny):
+        * b3/air/AirInstInlines.h:
+        * b3/testb3.cpp:
+        (JSC::B3::testSimplePatchpoint):
+
 2015-11-03  Benjamin Poulain  <bpoulain@apple.com>
 
         [JSC] Add Air lowering for BitOr and impove BitAnd
index c3af112..aaf1f70 100644 (file)
                0F300B7C18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F300B7A18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h */; };
                0F32BD101BB34F190093A57F /* HeapHelperPool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F32BD0E1BB34F190093A57F /* HeapHelperPool.cpp */; };
                0F32BD111BB34F190093A57F /* HeapHelperPool.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F32BD0F1BB34F190093A57F /* HeapHelperPool.h */; };
+               0F338DF11BE93AD10013C88F /* B3StackmapValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338DEF1BE93AD10013C88F /* B3StackmapValue.cpp */; };
+               0F338DF21BE93AD10013C88F /* B3StackmapValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338DF01BE93AD10013C88F /* B3StackmapValue.h */; };
+               0F338DF51BE93D550013C88F /* B3ConstrainedValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F338DF31BE93D550013C88F /* B3ConstrainedValue.cpp */; };
+               0F338DF61BE93D550013C88F /* B3ConstrainedValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F338DF41BE93D550013C88F /* B3ConstrainedValue.h */; };
                0F34B14916D42010001CDA5A /* DFGUseKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */; };
                0F34B14A16D42013001CDA5A /* DFGUseKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F34B14816D4200E001CDA5A /* DFGUseKind.h */; };
                0F38B01117CF078000B144D3 /* LLIntEntrypoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F38B00F17CF077F00B144D3 /* LLIntEntrypoint.cpp */; };
                0FEC852B1BDACDAC0080FF74 /* B3Procedure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEC84E11BDACDAC0080FF74 /* B3Procedure.cpp */; };
                0FEC852C1BDACDAC0080FF74 /* B3Procedure.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84E21BDACDAC0080FF74 /* B3Procedure.h */; };
                0FEC852D1BDACDAC0080FF74 /* B3ProcedureInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84E31BDACDAC0080FF74 /* B3ProcedureInlines.h */; };
-               0FEC852E1BDACDAC0080FF74 /* B3Stackmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEC84E41BDACDAC0080FF74 /* B3Stackmap.cpp */; };
-               0FEC852F1BDACDAC0080FF74 /* B3Stackmap.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84E51BDACDAC0080FF74 /* B3Stackmap.h */; };
                0FEC85301BDACDAC0080FF74 /* B3StackmapSpecial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEC84E61BDACDAC0080FF74 /* B3StackmapSpecial.cpp */; };
                0FEC85311BDACDAC0080FF74 /* B3StackmapSpecial.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84E71BDACDAC0080FF74 /* B3StackmapSpecial.h */; };
                0FEC85321BDACDAC0080FF74 /* B3StackSlotKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEC84E81BDACDAC0080FF74 /* B3StackSlotKind.cpp */; };
                0F300B7A18AB1B1400A6D72E /* DFGIntegerCheckCombiningPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGIntegerCheckCombiningPhase.h; path = dfg/DFGIntegerCheckCombiningPhase.h; sourceTree = "<group>"; };
                0F32BD0E1BB34F190093A57F /* HeapHelperPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HeapHelperPool.cpp; sourceTree = "<group>"; };
                0F32BD0F1BB34F190093A57F /* HeapHelperPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapHelperPool.h; sourceTree = "<group>"; };
+               0F338DEF1BE93AD10013C88F /* B3StackmapValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3StackmapValue.cpp; path = b3/B3StackmapValue.cpp; sourceTree = "<group>"; };
+               0F338DF01BE93AD10013C88F /* B3StackmapValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3StackmapValue.h; path = b3/B3StackmapValue.h; sourceTree = "<group>"; };
+               0F338DF31BE93D550013C88F /* B3ConstrainedValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3ConstrainedValue.cpp; path = b3/B3ConstrainedValue.cpp; sourceTree = "<group>"; };
+               0F338DF41BE93D550013C88F /* B3ConstrainedValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ConstrainedValue.h; path = b3/B3ConstrainedValue.h; sourceTree = "<group>"; };
                0F34B14716D4200E001CDA5A /* DFGUseKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGUseKind.cpp; path = dfg/DFGUseKind.cpp; sourceTree = "<group>"; };
                0F34B14816D4200E001CDA5A /* DFGUseKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGUseKind.h; path = dfg/DFGUseKind.h; sourceTree = "<group>"; };
                0F38B00F17CF077F00B144D3 /* LLIntEntrypoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntEntrypoint.cpp; path = llint/LLIntEntrypoint.cpp; sourceTree = "<group>"; };
                0FEC84E11BDACDAC0080FF74 /* B3Procedure.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3Procedure.cpp; path = b3/B3Procedure.cpp; sourceTree = "<group>"; };
                0FEC84E21BDACDAC0080FF74 /* B3Procedure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3Procedure.h; path = b3/B3Procedure.h; sourceTree = "<group>"; };
                0FEC84E31BDACDAC0080FF74 /* B3ProcedureInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ProcedureInlines.h; path = b3/B3ProcedureInlines.h; sourceTree = "<group>"; };
-               0FEC84E41BDACDAC0080FF74 /* B3Stackmap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3Stackmap.cpp; path = b3/B3Stackmap.cpp; sourceTree = "<group>"; };
-               0FEC84E51BDACDAC0080FF74 /* B3Stackmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3Stackmap.h; path = b3/B3Stackmap.h; sourceTree = "<group>"; };
                0FEC84E61BDACDAC0080FF74 /* B3StackmapSpecial.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3StackmapSpecial.cpp; path = b3/B3StackmapSpecial.cpp; sourceTree = "<group>"; };
                0FEC84E71BDACDAC0080FF74 /* B3StackmapSpecial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3StackmapSpecial.h; path = b3/B3StackmapSpecial.h; sourceTree = "<group>"; };
                0FEC84E81BDACDAC0080FF74 /* B3StackSlotKind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3StackSlotKind.cpp; path = b3/B3StackSlotKind.cpp; sourceTree = "<group>"; };
                                0FEC84C71BDACDAC0080FF74 /* B3ConstDoubleValue.cpp */,
                                0FEC84C81BDACDAC0080FF74 /* B3ConstDoubleValue.h */,
                                0FEC85B21BDED9570080FF74 /* B3ConstPtrValue.h */,
+                               0F338DF31BE93D550013C88F /* B3ConstrainedValue.cpp */,
+                               0F338DF41BE93D550013C88F /* B3ConstrainedValue.h */,
                                0FEC84C91BDACDAC0080FF74 /* B3ControlValue.cpp */,
                                0FEC84CA1BDACDAC0080FF74 /* B3ControlValue.h */,
                                0FEC85C41BE16F5A0080FF74 /* B3Effects.cpp */,
                                0FEC84E31BDACDAC0080FF74 /* B3ProcedureInlines.h */,
                                0FEC85B71BE1462F0080FF74 /* B3ReduceStrength.cpp */,
                                0FEC85B81BE1462F0080FF74 /* B3ReduceStrength.h */,
-                               0FEC84E41BDACDAC0080FF74 /* B3Stackmap.cpp */,
-                               0FEC84E51BDACDAC0080FF74 /* B3Stackmap.h */,
                                0FEC84E61BDACDAC0080FF74 /* B3StackmapSpecial.cpp */,
                                0FEC84E71BDACDAC0080FF74 /* B3StackmapSpecial.h */,
+                               0F338DEF1BE93AD10013C88F /* B3StackmapValue.cpp */,
+                               0F338DF01BE93AD10013C88F /* B3StackmapValue.h */,
                                0FEC84E81BDACDAC0080FF74 /* B3StackSlotKind.cpp */,
                                0FEC84E91BDACDAC0080FF74 /* B3StackSlotKind.h */,
                                0FEC84EA1BDACDAC0080FF74 /* B3StackSlotValue.cpp */,
                                0FEC852C1BDACDAC0080FF74 /* B3Procedure.h in Headers */,
                                0FEC852D1BDACDAC0080FF74 /* B3ProcedureInlines.h in Headers */,
                                0FEC85BD1BE1462F0080FF74 /* B3ReduceStrength.h in Headers */,
-                               0FEC852F1BDACDAC0080FF74 /* B3Stackmap.h in Headers */,
                                0FEC85311BDACDAC0080FF74 /* B3StackmapSpecial.h in Headers */,
                                0FEC85331BDACDAC0080FF74 /* B3StackSlotKind.h in Headers */,
                                0FEC85351BDACDAC0080FF74 /* B3StackSlotValue.h in Headers */,
                                79C4B15E1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h in Headers */,
                                A7D89CFC17A0B8CC00773AD8 /* DFGLivenessAnalysisPhase.h in Headers */,
                                0FF0F19B16B729FA005DF95B /* DFGLongLivedState.h in Headers */,
+                               0F338DF21BE93AD10013C88F /* B3StackmapValue.h in Headers */,
                                A767B5B617A0B9650063D940 /* DFGLoopPreHeaderCreationPhase.h in Headers */,
                                79F8FC1F1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.h in Headers */,
                                0F5874EE194FEB1200AAB2C1 /* DFGMayExit.h in Headers */,
                                A5EA710519F6DE740098F5EC /* generate_objc_configuration_header.py in Headers */,
                                A5EA710619F6DE760098F5EC /* generate_objc_configuration_implementation.py in Headers */,
                                A5EA710719F6DE780098F5EC /* generate_objc_conversion_helpers.py in Headers */,
+                               0F338DF61BE93D550013C88F /* B3ConstrainedValue.h in Headers */,
                                A5EA710819F6DE7A0098F5EC /* generate_objc_frontend_dispatcher_implementation.py in Headers */,
                                A5EA710919F6DE7C0098F5EC /* generate_objc_header.py in Headers */,
                                A5EA710A19F6DE7E0098F5EC /* generate_objc_internal_header.py in Headers */,
                                0FEC85291BDACDAC0080FF74 /* B3PhaseScope.cpp in Sources */,
                                0FEC852B1BDACDAC0080FF74 /* B3Procedure.cpp in Sources */,
                                0FEC85BC1BE1462F0080FF74 /* B3ReduceStrength.cpp in Sources */,
-                               0FEC852E1BDACDAC0080FF74 /* B3Stackmap.cpp in Sources */,
                                0FEC85301BDACDAC0080FF74 /* B3StackmapSpecial.cpp in Sources */,
                                0FEC85321BDACDAC0080FF74 /* B3StackSlotKind.cpp in Sources */,
                                0FEC85341BDACDAC0080FF74 /* B3StackSlotValue.cpp in Sources */,
                                0F485329187DFDEC0083B687 /* FTLRecoveryOpcode.cpp in Sources */,
                                0FCEFAAB1804C13E00472CE4 /* FTLSaveRestore.cpp in Sources */,
                                0F25F1B1181635F300522F39 /* FTLSlowPathCall.cpp in Sources */,
+                               0F338DF11BE93AD10013C88F /* B3StackmapValue.cpp in Sources */,
                                0F25F1B3181635F300522F39 /* FTLSlowPathCallKey.cpp in Sources */,
                                0F9D339A1803ADB70073C2BC /* FTLStackMaps.cpp in Sources */,
                                0FEA0A161706BB9000BB722C /* FTLState.cpp in Sources */,
                                9330402C0E6A764000786E6A /* SmallStrings.cpp in Sources */,
                                0F8F2B9E17306C8D007DBDA5 /* SourceCode.cpp in Sources */,
                                0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */,
+                               0F338DF51BE93D550013C88F /* B3ConstrainedValue.cpp in Sources */,
                                E49DC16B12EF293E00184A1F /* SourceProviderCache.cpp in Sources */,
                                0F0CD4C415F6B6BB0032F1C0 /* SparseArrayValueMap.cpp in Sources */,
                                0F5541B11613C1FB00CE3E25 /* SpecialPointer.cpp in Sources */,
index f2dec8d..cdd1135 100644 (file)
@@ -34,9 +34,9 @@ ArgumentRegValue::~ArgumentRegValue()
 {
 }
 
-void ArgumentRegValue::dumpMeta(PrintStream& out) const
+void ArgumentRegValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
 {
-    out.print(m_reg);
+    out.print(comma, m_reg);
 }
 
 } } // namespace JSC::B3
index 8f8fe4c..cbd0f4f 100644 (file)
@@ -42,7 +42,7 @@ public:
     Reg argumentReg() const { return m_reg; }
 
 protected:
-    void dumpMeta(PrintStream&) const override;
+    void dumpMeta(CommaPrinter&, PrintStream&) const override;
 
 private:
     friend class Procedure;
index f614225..66274b9 100644 (file)
@@ -101,7 +101,8 @@ CCallHelpers::Jump CheckSpecial::generate(Inst& inst, CCallHelpers& jit, Generat
     CCallHelpers::Jump fail = hiddenBranch(inst).generate(jit, context);
     ASSERT(fail.isSet());
 
-    Value* value = inst.origin;
+    StackmapValue* value = inst.origin->as<StackmapValue>();
+    ASSERT(value);
 
     Vector<ValueRep> reps;
     if (isCheckMath(value->opcode())) {
@@ -124,16 +125,12 @@ CCallHelpers::Jump CheckSpecial::generate(Inst& inst, CCallHelpers& jit, Generat
             [=] (CCallHelpers& jit, GenerationContext&) {
                 fail.link(&jit);
                 
-                Stackmap* stackmap = value->stackmap();
-                ASSERT(stackmap);
-
-                Stackmap::GenerationParams params;
+                StackmapGenerationParams params;
                 params.value = value;
-                params.stackmap = stackmap;
                 params.reps = reps;
-                params.usedRegisters = stackmap->m_usedRegisters;
+                params.usedRegisters = value->m_usedRegisters;
 
-                stackmap->m_generator->run(jit, params);
+                value->m_generator->run(jit, params);
             }));
 
     return CCallHelpers::Jump(); // As far as Air thinks, we are not a terminal.
index 15db2a2..9212300 100644 (file)
@@ -34,9 +34,23 @@ CheckValue::~CheckValue()
 {
 }
 
-void CheckValue::dumpMeta(PrintStream& out) const
+// Use this form for CheckAdd, CheckSub, and CheckMul.
+CheckValue::CheckValue(unsigned index, Opcode opcode, Origin origin, Value* left, Value* right)
+    : StackmapValue(index, opcode, left->type(), origin)
 {
-    out.print("stackmap = ", stackmap);
+    ASSERT(B3::isInt(type()));
+    ASSERT(left->type() == right->type());
+    ASSERT(opcode == CheckAdd || opcode == CheckSub || opcode == CheckMul);
+    append(ConstrainedValue(left, ValueRep::SomeRegister));
+    append(ConstrainedValue(right, ValueRep::SomeRegister));
+}
+
+// Use this form for Check.
+CheckValue::CheckValue(unsigned index, Opcode opcode, Origin origin, Value* predicate)
+    : StackmapValue(index, opcode, Void, origin)
+{
+    ASSERT(opcode == Check);
+    append(predicate);
 }
 
 } } // namespace JSC::B3
index 172044e..781eed6 100644 (file)
 
 #if ENABLE(B3_JIT)
 
-#include "B3Stackmap.h"
-#include "B3Value.h"
+#include "B3StackmapValue.h"
 
 namespace JSC { namespace B3 {
 
-class JS_EXPORT_PRIVATE CheckValue : public Value {
+class CheckValue : public StackmapValue {
 public:
     static bool accepts(Opcode opcode)
     {
@@ -50,29 +49,14 @@ public:
 
     ~CheckValue();
 
-    Stackmap stackmap;
-
-protected:
-    void dumpMeta(PrintStream&) const override;
-
 private:
     friend class Procedure;
 
     // Use this form for CheckAdd, CheckSub, and CheckMul.
-    CheckValue(unsigned index, Opcode opcode, Origin origin, Value* left, Value* right)
-        : Value(index, opcode, left->type(), origin, left, right)
-    {
-        ASSERT(B3::isInt(type()));
-        ASSERT(left->type() == right->type());
-        ASSERT(opcode == CheckAdd || opcode == CheckSub || opcode == CheckMul);
-    }
+    JS_EXPORT_PRIVATE CheckValue(unsigned index, Opcode, Origin, Value* left, Value* right);
 
     // Use this form for Check.
-    CheckValue(unsigned index, Opcode opcode, Origin origin, Value* predicate)
-        : Value(index, opcode, Void, origin, predicate)
-    {
-        ASSERT(opcode == Check);
-    }
+    JS_EXPORT_PRIVATE CheckValue(unsigned index, Opcode, Origin, Value* predicate);
 };
 
 } } // namespace JSC::B3
index 2d59f41..2c85e90 100644 (file)
@@ -89,9 +89,9 @@ Value* Const32Value::notEqualConstant(Procedure& proc, Value* other) const
     return proc.add<Const32Value>(origin(), m_value != other->asInt32());
 }
 
-void Const32Value::dumpMeta(PrintStream& out) const
+void Const32Value::dumpMeta(CommaPrinter& comma, PrintStream& out) const
 {
-    out.print(m_value);
+    out.print(comma, m_value);
 }
 
 } } // namespace JSC::B3
index bf0281e..afed120 100644 (file)
@@ -50,7 +50,7 @@ public:
     Value* notEqualConstant(Procedure&, Value* other) const override;
 
 protected:
-    JS_EXPORT_PRIVATE void dumpMeta(PrintStream&) const override;
+    JS_EXPORT_PRIVATE void dumpMeta(CommaPrinter&, PrintStream&) const override;
 
     friend class Procedure;
 
index eaefa31..5e7f83b 100644 (file)
@@ -89,9 +89,9 @@ Value* Const64Value::notEqualConstant(Procedure& proc, Value* other) const
     return proc.add<Const32Value>(origin(), m_value != other->asInt64());
 }
 
-void Const64Value::dumpMeta(PrintStream& out) const
+void Const64Value::dumpMeta(CommaPrinter& comma, PrintStream& out) const
 {
-    out.print(m_value);
+    out.print(comma, m_value);
 }
 
 } } // namespace JSC::B3
index cf352a5..58b994a 100644 (file)
@@ -50,7 +50,7 @@ public:
     Value* notEqualConstant(Procedure&, Value* other) const override;
 
 protected:
-    void dumpMeta(PrintStream&) const override;
+    void dumpMeta(CommaPrinter&, PrintStream&) const override;
 
     friend class Procedure;
 
index 049eb35..42fb8e1 100644 (file)
@@ -75,8 +75,9 @@ Value* ConstDoubleValue::notEqualConstant(Procedure& proc, Value* other) const
     return proc.add<Const32Value>(origin(), m_value != other->asDouble());
 }
 
-void ConstDoubleValue::dumpMeta(PrintStream& out) const
+void ConstDoubleValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
 {
+    out.print(comma);
     out.printf("%le", m_value);
 }
 
index c0db630..d528972 100644 (file)
@@ -48,7 +48,7 @@ public:
     Value* notEqualConstant(Procedure& proc, Value* other) const override;
 
 protected:
-    void dumpMeta(PrintStream&) const override;
+    void dumpMeta(CommaPrinter&, PrintStream&) const override;
 
 private:
     friend class Procedure;
similarity index 81%
rename from Source/JavaScriptCore/b3/B3Stackmap.cpp
rename to Source/JavaScriptCore/b3/B3ConstrainedValue.cpp
index a3e56b2..dd1762f 100644 (file)
  */
 
 #include "config.h"
-#include "B3Stackmap.h"
+#include "B3ConstrainedValue.h"
 
 #if ENABLE(B3_JIT)
 
-#include <wtf/ListDump.h>
+#include "B3Value.h"
 
 namespace JSC { namespace B3 {
 
-Stackmap::Stackmap()
+void ConstrainedValue::dump(PrintStream& out) const
 {
-}
-
-Stackmap::~Stackmap()
-{
-}
-
-void Stackmap::dump(PrintStream& out) const
-{
-    out.print(
-        "{reps = ", listDump(m_reps), ", generator = ", RawPointer(m_generator.get()),
-        ", clobbered = ", m_clobbered, ", usedRegisters = ", m_usedRegisters, "}");
+    out.print(pointerDump(m_value), ":", m_rep);
 }
 
 } } // namespace JSC::B3
diff --git a/Source/JavaScriptCore/b3/B3ConstrainedValue.h b/Source/JavaScriptCore/b3/B3ConstrainedValue.h
new file mode 100644 (file)
index 0000000..c77d035
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 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 B3ConstrainedValue_h
+#define B3ConstrainedValue_h
+
+#if ENABLE(B3_JIT)
+
+#include "B3ValueRep.h"
+
+namespace JSC { namespace B3 {
+
+class Value;
+
+class ConstrainedValue {
+public:
+    ConstrainedValue()
+    {
+    }
+
+    ConstrainedValue(Value* value)
+        : m_value(value)
+        , m_rep(ValueRep::Any)
+    {
+    }
+
+    ConstrainedValue(Value* value, const ValueRep& rep)
+        : m_value(value)
+        , m_rep(rep)
+    {
+    }
+
+    explicit operator bool() const { return m_value || m_rep; }
+
+    Value* value() const { return m_value; }
+    const ValueRep& rep() const { return m_rep; }
+
+    void dump(PrintStream& out) const;
+
+private:
+    Value* m_value;
+    ValueRep m_rep;
+};
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3ConstrainedValue_h
+
index 253342f..02970d3 100644 (file)
@@ -29,7 +29,6 @@
 #if ENABLE(B3_JIT)
 
 #include "B3BasicBlock.h"
-#include <wtf/ListDump.h>
 
 namespace JSC { namespace B3 {
 
@@ -50,9 +49,10 @@ void ControlValue::convertToJump(const FrequentedBlock& destination)
     this->owner = owner;
 }
 
-void ControlValue::dumpMeta(PrintStream& out) const
+void ControlValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
 {
-    out.print(listDump(m_successors));
+    for (FrequentedBlock successor : m_successors)
+        out.print(comma, successor);
 }
 
 } } // namespace JSC::B3
index 34b1f63..bee39d7 100644 (file)
@@ -88,7 +88,7 @@ public:
     void convertToJump(const FrequentedBlock& destination);
 
 protected:
-    JS_EXPORT_PRIVATE void dumpMeta(PrintStream&) const override;
+    JS_EXPORT_PRIVATE void dumpMeta(CommaPrinter&, PrintStream&) const override;
 
     // Use this for subclasses.
     template<typename... Arguments>
index 5032185..ea0de49 100644 (file)
@@ -791,26 +791,22 @@ public:
         if (patchpointValue->type() != Void)
             inst.args.append(tmp(patchpointValue));
 
-        for (unsigned i = 0; i < patchpointValue->numChildren(); ++i) {
-            ValueRep rep;
-            if (i < patchpointValue->stackmap.reps().size())
-                rep = patchpointValue->stackmap.reps()[i];
-
+        for (ConstrainedValue value : patchpointValue->constrainedChildren()) {
             Arg arg;
-            switch (rep.kind()) {
+            switch (value.rep().kind()) {
             case ValueRep::Any:
-                arg = immOrTmp(patchpointValue->child(i));
+                arg = immOrTmp(value.value());
                 break;
             case ValueRep::SomeRegister:
-                arg = tmp(patchpointValue->child(i));
+                arg = tmp(value.value());
                 break;
             case ValueRep::Register:
-                arg = Tmp(rep.reg());
-                append(Move, immOrTmp(patchpointValue->child(i)), arg);
+                arg = Tmp(value.rep().reg());
+                append(Move, immOrTmp(value.value()), arg);
                 break;
             case ValueRep::StackArgument:
-                arg = Arg::callArg(rep.offsetFromSP());
-                appendStore(patchpointValue->child(i), arg);
+                arg = Arg::callArg(value.rep().offsetFromSP());
+                appendStore(value.value(), arg);
                 break;
             default:
                 RELEASE_ASSERT_NOT_REACHED();
index 687d729..fa56225 100644 (file)
@@ -58,10 +58,10 @@ size_t MemoryValue::accessByteSize() const
     }
 }
 
-void MemoryValue::dumpMeta(PrintStream& out) const
+void MemoryValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
 {
     if (m_offset)
-        out.print("offset = ", m_offset);
+        out.print(comma, "offset = ", m_offset);
 }
 
 } } // namespace JSC::B3
index 6c35369..2e4d4ee 100644 (file)
@@ -65,7 +65,7 @@ public:
     size_t accessByteSize() const;
 
 protected:
-    void dumpMeta(PrintStream&) const override;
+    void dumpMeta(CommaPrinter& comma, PrintStream&) const override;
 
 private:
     friend class Procedure;
index c9979c8..97108ea 100644 (file)
@@ -84,9 +84,8 @@ bool PatchpointSpecial::admitsStack(Inst& inst, unsigned argIndex)
 CCallHelpers::Jump PatchpointSpecial::generate(
     Inst& inst, CCallHelpers& jit, GenerationContext& context)
 {
-    Value* value = inst.origin;
-    Stackmap* stackmap = value->stackmap();
-    ASSERT(stackmap);
+    StackmapValue* value = inst.origin->as<StackmapValue>();
+    ASSERT(value);
 
     Vector<ValueRep> reps;
     unsigned offset = 1;
@@ -94,13 +93,12 @@ CCallHelpers::Jump PatchpointSpecial::generate(
         reps.append(repForArg(*context.code, inst.args[offset++]));
     appendRepsImpl(context, offset, inst, reps);
     
-    Stackmap::GenerationParams params;
+    StackmapGenerationParams params;
     params.value = value;
-    params.stackmap = stackmap;
     params.reps = reps;
-    params.usedRegisters = stackmap->m_usedRegisters;
+    params.usedRegisters = value->m_usedRegisters;
 
-    stackmap->m_generator->run(jit, params);
+    value->m_generator->run(jit, params);
 
     return CCallHelpers::Jump();
 }
index 832acab..52012ea 100644 (file)
@@ -34,9 +34,9 @@ PatchpointValue::~PatchpointValue()
 {
 }
 
-void PatchpointValue::dumpMeta(PrintStream& out) const
+PatchpointValue::PatchpointValue(unsigned index, Type type, Origin origin)
+    : StackmapValue(index, Patchpoint, type, origin)
 {
-    out.print("stackmap = ", stackmap);
 }
 
 } } // namespace JSC::B3
index 66c490f..1c0945d 100644 (file)
 
 #if ENABLE(B3_JIT)
 
-#include "B3Stackmap.h"
-#include "B3Value.h"
+#include "B3StackmapValue.h"
 
 namespace JSC { namespace B3 {
 
-class JS_EXPORT_PRIVATE PatchpointValue : public Value {
+class PatchpointValue : public StackmapValue {
 public:
     static bool accepts(Opcode opcode) { return opcode == Patchpoint; }
 
     ~PatchpointValue();
 
-    Stackmap stackmap;
-
-protected:
-    void dumpMeta(PrintStream&) const override;
-
 private:
     friend class Procedure;
 
-    template<typename ListType>
-    PatchpointValue(unsigned index, Type type, Origin origin, ListType&& children)
-        : Value(index, Patchpoint, type, origin, std::forward<ListType>(children))
-    {
-    }
-
-    // It's totally fine to create a PatchpointValue without any children, and then append the
-    // children as you build up the stackmap.
-    PatchpointValue(unsigned index, Type type, Origin origin)
-        : Value(index, Patchpoint, type, origin, AdjacencyList())
-    {
-    }
+    JS_EXPORT_PRIVATE PatchpointValue(unsigned index, Type, Origin);
 };
 
 } } // namespace JSC::B3
index aef8487..e404e64 100644 (file)
@@ -34,9 +34,9 @@ StackSlotValue::~StackSlotValue()
 {
 }
 
-void StackSlotValue::dumpMeta(PrintStream& out) const
+void StackSlotValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
 {
-    out.print("byteSize = ", m_byteSize, ", kind = ", m_kind);
+    out.print(comma, "byteSize = ", m_byteSize, ", kind = ", m_kind);
 }
 
 } } // namespace JSC::B3
index 92e9767..d5c4323 100644 (file)
@@ -57,7 +57,7 @@ public:
     }
 
 protected:
-    void dumpMeta(PrintStream&) const override;
+    void dumpMeta(CommaPrinter&, PrintStream&) const override;
 
 private:
     friend class Air::StackSlot;
diff --git a/Source/JavaScriptCore/b3/B3Stackmap.h b/Source/JavaScriptCore/b3/B3Stackmap.h
deleted file mode 100644 (file)
index 12eea28..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2015 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 B3Stackmap_h
-#define B3Stackmap_h
-
-#if ENABLE(B3_JIT)
-
-#include "B3ValueRep.h"
-#include "CCallHelpers.h"
-#include "RegisterSet.h"
-#include <wtf/SharedTask.h>
-
-namespace JSC { namespace B3 {
-
-class CheckSpecial;
-class StackmapSpecial;
-class Value;
-
-class Stackmap {
-public:
-    struct GenerationParams {
-        // This is the Value containing the stackmap.
-        Value* value;
-
-        // This is the stackmap.
-        Stackmap* stackmap;
-
-        // This tells you the actual value representations that were chosen.
-        Vector<ValueRep> reps;
-
-        // This tells you the registers that were used.
-        RegisterSet usedRegisters;
-    };
-    
-    typedef void GeneratorFunction(CCallHelpers&, const GenerationParams&);
-    typedef SharedTask<GeneratorFunction> Generator;
-    
-    JS_EXPORT_PRIVATE Stackmap();
-    ~Stackmap();
-
-    // Constrain an argument to the Value that uses this Stackmap. In case of a Patchpoint that
-    // returns a value, the first argument is the result value. In all other cases, index zero refers
-    // to the first argument to that Value, even if that argument is not constrainable. For example,
-    // in a CheckAdd value, it would be an error to constrain indices 0 and 1. In a Check value, it
-    // would be an error to constrain index 0. But, when the generation callback is called, you can
-    // depend on the reps for those indices being filled in.
-    void constrain(unsigned index, const ValueRep& rep)
-    {
-        if (index + 1 >= m_reps.size())
-            m_reps.grow(index + 1);
-        m_reps[index] = rep;
-    }
-
-    void appendConstraint(const ValueRep& rep)
-    {
-        m_reps.append(rep);
-    }
-
-    const Vector<ValueRep>& reps() const { return m_reps; }
-
-    void clobber(const RegisterSet& set)
-    {
-        m_clobbered.merge(set);
-    }
-
-    const RegisterSet& clobbered() const { return m_clobbered; }
-
-    void setGenerator(RefPtr<Generator> generator)
-    {
-        m_generator = generator;
-    }
-
-    template<typename Functor>
-    void setGenerator(const Functor& functor)
-    {
-        m_generator = createSharedTask<GeneratorFunction>(functor);
-    }
-
-    void dump(PrintStream&) const;
-    
-private:
-    friend class CheckSpecial;
-    friend class PatchpointSpecial;
-    friend class StackmapSpecial;
-    
-    Vector<ValueRep> m_reps;
-    RefPtr<Generator> m_generator;
-    RegisterSet m_clobbered;
-    RegisterSet m_usedRegisters; // Stackmaps could be further duplicated by Air, but that's unlikely, so we just merge the used registers sets if that were to happen.
-};
-
-} } // namespace JSC::B3
-
-#endif // ENABLE(B3_JIT)
-
-#endif // B3Stackmap_h
-
index 10587ab..8c70222 100644 (file)
@@ -46,21 +46,21 @@ StackmapSpecial::~StackmapSpecial()
 
 void StackmapSpecial::reportUsedRegisters(Inst& inst, const RegisterSet& usedRegisters)
 {
-    Value* value = inst.origin;
-    Stackmap* stackmap = value->stackmap();
+    StackmapValue* value = inst.origin->as<StackmapValue>();
+    ASSERT(value);
 
     // FIXME: If the Inst that uses the StackmapSpecial gets duplicated, then we end up merging used
     // register sets from multiple places. This currently won't happen since Air doesn't have taildup
     // or things like that. But maybe eventually it could be a problem.
-    stackmap->m_usedRegisters.merge(usedRegisters);
+    value->m_usedRegisters.merge(usedRegisters);
 }
 
 const RegisterSet& StackmapSpecial::extraClobberedRegs(Inst& inst)
 {
-    Value* value = inst.origin;
-    Stackmap* stackmap = value->stackmap();
+    StackmapValue* value = inst.origin->as<StackmapValue>();
+    ASSERT(value);
 
-    return stackmap->clobbered();
+    return value->clobbered();
 }
 
 void StackmapSpecial::forEachArgImpl(
@@ -86,16 +86,13 @@ bool StackmapSpecial::isValidImpl(
     unsigned numIgnoredB3Args, unsigned numIgnoredAirArgs,
     Inst& inst)
 {
-    Value* value = inst.origin;
+    StackmapValue* value = inst.origin->as<StackmapValue>();
+    ASSERT(value);
 
     // Check that insane things have not happened.
     ASSERT(inst.args.size() >= numIgnoredAirArgs);
     ASSERT(value->children().size() >= numIgnoredB3Args);
 
-    Stackmap* stackmap = value->stackmap();
-
-    ASSERT(stackmap);
-
     // For the Inst to be valid, it needs to have the right number of arguments.
     if (inst.args.size() - numIgnoredAirArgs != value->children().size() - numIgnoredB3Args)
         return false;
@@ -130,11 +127,11 @@ bool StackmapSpecial::isValidImpl(
     }
 
     // The number of constraints has to be no greater than the number of B3 children.
-    ASSERT(stackmap->m_reps.size() <= value->children().size());
+    ASSERT(value->m_reps.size() <= value->children().size());
 
     // Verify any explicitly supplied constraints.
-    for (unsigned i = numIgnoredB3Args; i < stackmap->m_reps.size(); ++i) {
-        ValueRep& rep = stackmap->m_reps[i];
+    for (unsigned i = numIgnoredB3Args; i < value->m_reps.size(); ++i) {
+        ValueRep& rep = value->m_reps[i];
         Arg& arg = inst.args[i - numIgnoredB3Args + numIgnoredAirArgs];
 
         switch (rep.kind()) {
@@ -171,19 +168,19 @@ bool StackmapSpecial::admitsStackImpl(
     unsigned numIgnoredB3Args, unsigned numIgnoredAirArgs,
     Inst& inst, unsigned argIndex)
 {
-    Value* value = inst.origin;
-    Stackmap* stackmap = value->stackmap();
+    StackmapValue* value = inst.origin->as<StackmapValue>();
+    ASSERT(value);
 
     unsigned stackmapArgIndex = argIndex - numIgnoredAirArgs + numIgnoredB3Args;
 
-    if (stackmapArgIndex >= stackmap->m_reps.size()) {
+    if (stackmapArgIndex >= value->m_reps.size()) {
         // This means that there was no constraint.
         return true;
     }
     
     // We only admit stack for Any's, since Stack is not a valid input constraint, and StackArgument
     // translates to a CallArg in Air.
-    if (stackmap->m_reps[stackmapArgIndex].kind() == ValueRep::Any)
+    if (value->m_reps[stackmapArgIndex].kind() == ValueRep::Any)
         return true;
 
     return false;
index 80d013b..c09d999 100644 (file)
@@ -29,7 +29,7 @@
 #if ENABLE(B3_JIT)
 
 #include "AirSpecial.h"
-#include "B3Stackmap.h"
+#include "B3ValueRep.h"
 
 namespace JSC { namespace B3 {
 
diff --git a/Source/JavaScriptCore/b3/B3StackmapValue.cpp b/Source/JavaScriptCore/b3/B3StackmapValue.cpp
new file mode 100644 (file)
index 0000000..69a4722
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2015 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 "B3StackmapValue.h"
+
+#if ENABLE(B3_JIT)
+
+namespace JSC { namespace B3 {
+
+StackmapValue::~StackmapValue()
+{
+}
+
+void StackmapValue::append(const ConstrainedValue& constrainedValue)
+{
+    if (constrainedValue.rep() == ValueRep(ValueRep::Any)) {
+        children().append(constrainedValue.value());
+        return;
+    }
+
+    while (m_reps.size() < numChildren())
+        m_reps.append(ValueRep::Any);
+
+    children().append(constrainedValue.value());
+    m_reps.append(constrainedValue.rep());
+}
+
+void StackmapValue::setConstrainedChild(unsigned index, const ConstrainedValue& constrainedValue)
+{
+    child(index) = constrainedValue.value();
+    setConstraint(index, constrainedValue.rep());
+}
+
+void StackmapValue::setConstraint(unsigned index, const ValueRep& rep)
+{
+    if (rep == ValueRep(ValueRep::Any))
+        return;
+
+    while (m_reps.size() <= index)
+        m_reps.append(ValueRep::Any);
+
+    m_reps[index] = rep;
+}
+
+void StackmapValue::dumpChildren(CommaPrinter& comma, PrintStream& out) const
+{
+    for (ConstrainedValue value : constrainedChildren())
+        out.print(comma, value);
+}
+
+void StackmapValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
+{
+    out.print(
+        comma, "generator = ", RawPointer(m_generator.get()), ", clobbered = ", m_clobbered,
+        ", usedRegisters = ", m_usedRegisters);
+}
+
+StackmapValue::StackmapValue(unsigned index, Opcode opcode, Type type, Origin origin)
+    : Value(index, opcode, type, origin)
+{
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
diff --git a/Source/JavaScriptCore/b3/B3StackmapValue.h b/Source/JavaScriptCore/b3/B3StackmapValue.h
new file mode 100644 (file)
index 0000000..95cc69b
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2015 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 B3StackmapValue_h
+#define B3StackmapValue_h
+
+#if ENABLE(B3_JIT)
+
+#include "B3ConstrainedValue.h"
+#include "B3Value.h"
+#include "B3ValueRep.h"
+#include "CCallHelpers.h"
+#include "RegisterSet.h"
+#include <wtf/SharedTask.h>
+
+namespace JSC { namespace B3 {
+
+class StackmapValue;
+
+struct StackmapGenerationParams {
+    // This is the stackmap value that we're generating.
+    StackmapValue* value;
+    
+    // This tells you the actual value representations that were chosen. This is usually different
+    // from the constraints we supplied.
+    Vector<ValueRep> reps;
+    
+    // This tells you the registers that were used.
+    RegisterSet usedRegisters;
+};
+
+typedef void StackmapGeneratorFunction(CCallHelpers&, const StackmapGenerationParams&);
+typedef SharedTask<StackmapGeneratorFunction> StackmapGenerator;
+
+class JS_EXPORT_PRIVATE StackmapValue : public Value {
+public:
+    static bool accepts(Opcode opcode)
+    {
+        // This needs to include opcodes of all subclasses.
+        switch (opcode) {
+        case CheckAdd:
+        case CheckSub:
+        case CheckMul:
+        case Check:
+        case Patchpoint:
+            return true;
+        default:
+            return false;
+        }
+    }
+
+    ~StackmapValue();
+
+    // Use this to add children. Note that you could also add children by doing
+    // children().append(). That will work fine, but it's not recommended.
+    void append(const ConstrainedValue&);
+
+    const Vector<ValueRep>& reps() const { return m_reps; }
+
+    void clobber(const RegisterSet& set)
+    {
+        m_clobbered.merge(set);
+    }
+
+    const RegisterSet& clobbered() const { return m_clobbered; }
+
+    void setGenerator(RefPtr<StackmapGenerator> generator)
+    {
+        m_generator = generator;
+    }
+
+    template<typename Functor>
+    void setGenerator(const Functor& functor)
+    {
+        m_generator = createSharedTask<StackmapGeneratorFunction>(functor);
+    }
+
+    ConstrainedValue constrainedChild(unsigned index) const
+    {
+        return ConstrainedValue(child(index), index < m_reps.size() ? m_reps[index] : ValueRep());
+    }
+
+    void setConstrainedChild(unsigned index, const ConstrainedValue&);
+    
+    void setConstraint(unsigned index, const ValueRep&);
+
+    class ConstrainedValueCollection {
+    public:
+        ConstrainedValueCollection(const StackmapValue& value)
+            : m_value(value)
+        {
+        }
+
+        unsigned size() const { return m_value.numChildren(); }
+        
+        ConstrainedValue at(unsigned index) const { return m_value.constrainedChild(index); }
+
+        ConstrainedValue operator[](unsigned index) const { return at(index); }
+
+        class iterator {
+        public:
+            iterator()
+                : m_collection(nullptr)
+                , m_index(0)
+            {
+            }
+
+            iterator(const ConstrainedValueCollection& collection, unsigned index)
+                : m_collection(&collection)
+                , m_index(index)
+            {
+            }
+
+            ConstrainedValue operator*() const
+            {
+                return m_collection->at(m_index);
+            }
+
+            iterator& operator++()
+            {
+                m_index++;
+                return *this;
+            }
+
+            bool operator==(const iterator& other) const
+            {
+                ASSERT(m_collection == other.m_collection);
+                return m_index == other.m_index;
+            }
+
+            bool operator!=(const iterator& other) const
+            {
+                return !(*this == other);
+            }
+            
+        private:
+            const ConstrainedValueCollection* m_collection;
+            unsigned m_index;
+        };
+
+        iterator begin() const { return iterator(*this, 0); }
+        iterator end() const { return iterator(*this, size()); }
+
+    private:
+        const StackmapValue& m_value;
+    };
+
+    ConstrainedValueCollection constrainedChildren() const
+    {
+        return ConstrainedValueCollection(*this);
+    }
+
+protected:
+    void dumpChildren(CommaPrinter&, PrintStream&) const override;
+    void dumpMeta(CommaPrinter&, PrintStream&) const override;
+
+    StackmapValue(unsigned index, Opcode, Type, Origin);
+
+private:
+    friend class CheckSpecial;
+    friend class PatchpointSpecial;
+    friend class StackmapSpecial;
+    
+    Vector<ValueRep> m_reps;
+    RefPtr<StackmapGenerator> m_generator;
+    RegisterSet m_clobbered;
+    RegisterSet m_usedRegisters; // Stackmaps could be further duplicated by Air, but that's unlikely, so we just merge the used registers sets if that were to happen.
+};
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3StackmapValue_h
+
index ed799be..7a3eca0 100644 (file)
@@ -55,10 +55,12 @@ void SwitchValue::appendCase(const SwitchCase& switchCase)
     m_values.append(switchCase.caseValue());
 }
 
-void SwitchValue::dumpMeta(PrintStream& out) const
+void SwitchValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
 {
     // This destructively overrides ControlValue's dumpMeta().
-    out.print(listDump(*this), ", fallThrough = ", fallThrough());
+    for (SwitchCase switchCase : *this)
+        out.print(comma, switchCase);
+    out.print(comma, "fallThrough = ", fallThrough());
 }
 
 SwitchValue::SwitchValue(unsigned index, Origin origin, const FrequentedBlock& fallThrough)
index cb7cb90..960a9c0 100644 (file)
@@ -114,7 +114,7 @@ public:
     void appendCase(const SwitchCase&);
 
 protected:
-    void dumpMeta(PrintStream&) const override;
+    void dumpMeta(CommaPrinter&, PrintStream&) const override;
 
 private:
     friend class Procedure;
index 68a1af2..4c53f8d 100644 (file)
@@ -34,14 +34,14 @@ UpsilonValue::~UpsilonValue()
 {
 }
 
-void UpsilonValue::dumpMeta(PrintStream& out) const
+void UpsilonValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
 {
     if (m_phi)
-        out.print("^", m_phi->index());
+        out.print(comma, "^", m_phi->index());
     else {
         // We want to have a dump for when the Phi isn't set yet, since although such IR won't pass
         // validation, we may have such IR as an intermediate step.
-        out.print("^(null)");
+        out.print(comma, "^(null)");
     }
 }
 
index cbfd377..dec83de 100644 (file)
@@ -47,7 +47,7 @@ public:
     }
 
 protected:
-    void dumpMeta(PrintStream&) const override;
+    void dumpMeta(CommaPrinter&, PrintStream&) const override;
 
 private:
     friend class Procedure;
index d56d427..b7d7b95 100644 (file)
@@ -308,16 +308,17 @@ public:
 private:
     void validateStackmap(Value* value)
     {
-        Stackmap* stackmap = value->stackmap();
-        VALIDATE(value->numChildren() >= stackmap->reps().size(), ("At ", *value));
+        StackmapValue* stackmap = value->as<StackmapValue>();
+        VALIDATE(stackmap, ("At ", *value));
+        VALIDATE(stackmap->numChildren() >= stackmap->reps().size(), ("At ", *stackmap));
         for (unsigned i = 0; i < stackmap->reps().size(); ++i) {
             const ValueRep& rep = stackmap->reps()[i];
             if (rep.kind() != ValueRep::Register)
                 continue;
             if (rep.reg().isGPR())
-                VALIDATE(isInt(value->child(i)->type()), ("At ", *value));
+                VALIDATE(isInt(stackmap->child(i)->type()), ("At ", *stackmap));
             else
-                VALIDATE(isFloat(value->child(i)->type()), ("At ", *value));
+                VALIDATE(isFloat(stackmap->child(i)->type()), ("At ", *stackmap));
         }
     }
 
index 6f6834a..7590cc2 100644 (file)
@@ -78,25 +78,24 @@ void Value::dump(PrintStream& out) const
     out.print(dumpPrefix, m_index);
 }
 
+void Value::dumpChildren(CommaPrinter& comma, PrintStream& out) const
+{
+    for (Value* child : children())
+        out.print(comma, pointerDump(child));
+}
+
 void Value::deepDump(PrintStream& out) const
 {
     out.print(m_type, " ", *this, " = ", m_opcode);
 
     out.print("(");
     CommaPrinter comma;
-    for (Value* child : children())
-        out.print(comma, pointerDump(child));
+    dumpChildren(comma, out);
 
     if (m_origin)
         out.print(comma, m_origin);
 
-    {
-        StringPrintStream stringOut;
-        dumpMeta(stringOut);
-        CString string = stringOut.toCString();
-        if (string.length())
-            out.print(comma, string);
-    }
+    dumpMeta(comma, out);
 
     {
         CString string = toCString(effects());
@@ -294,7 +293,7 @@ void Value::performSubstitution()
     }
 }
 
-void Value::dumpMeta(PrintStream&) const
+void Value::dumpMeta(CommaPrinter&, PrintStream&) const
 {
 }
 
index 22c3cad..144dc2c 100644 (file)
@@ -33,6 +33,7 @@
 #include "B3Opcode.h"
 #include "B3Origin.h"
 #include "B3Type.h"
+#include <wtf/CommaPrinter.h>
 #include <wtf/FastMalloc.h>
 #include <wtf/Noncopyable.h>
 
@@ -40,7 +41,6 @@ namespace JSC { namespace B3 {
 
 class BasicBlock;
 class Procedure;
-class Stackmap;
 
 class JS_EXPORT_PRIVATE Value {
     WTF_MAKE_NONCOPYABLE(Value);
@@ -151,15 +151,14 @@ public:
     
     Effects effects() const;
 
-    Stackmap* stackmap();
-
     // Makes sure that none of the children are Identity's. If a child points to Identity, this will
     // repoint it at the Identity's child. For simplicity, this will follow arbitrarily long chains
     // of Identity's.
     void performSubstitution();
 
 protected:
-    virtual void dumpMeta(PrintStream&) const;
+    virtual void dumpChildren(CommaPrinter&, PrintStream&) const;
+    virtual void dumpMeta(CommaPrinter&, PrintStream&) const;
     
 private:
     friend class Procedure;
index d11f1c7..543f162 100644 (file)
@@ -178,15 +178,6 @@ inline T Value::asNumber() const
     }
 }
 
-inline Stackmap* Value::stackmap()
-{
-    if (CheckValue* check = as<CheckValue>())
-        return &check->stackmap;
-    if (PatchpointValue* patchpoint = as<PatchpointValue>())
-        return &patchpoint->stackmap;
-    return nullptr;
-}
-
 } } // namespace JSC::B3
 
 #endif // ENABLE(B3_JIT)
index aa63faf..1417a74 100644 (file)
@@ -121,6 +121,29 @@ public:
 
     Kind kind() const { return m_kind; }
 
+    bool operator==(const ValueRep& other) const
+    {
+        if (kind() != other.kind())
+            return false;
+        switch (kind()) {
+        case Register:
+            return u.reg == other.u.reg;
+        case Stack:
+            return u.offsetFromFP == other.u.offsetFromFP;
+        case StackArgument:
+            return u.offsetFromSP == other.u.offsetFromSP;
+        case Constant:
+            return u.value == other.u.value;
+        default:
+            return true;
+        }
+    }
+
+    bool operator!=(const ValueRep& other) const
+    {
+        return !(*this == other);
+    }
+
     explicit operator bool() const { return kind() != Any; }
 
     bool isAny() const { return kind() == Any; }
index 4e1cd7c..80670c6 100644 (file)
@@ -31,7 +31,6 @@
 #include "AirInst.h"
 #include "AirOpcodeUtils.h"
 #include "AirSpecial.h"
-#include "B3Stackmap.h"
 #include "B3Value.h"
 
 namespace JSC { namespace B3 { namespace Air {
index dcf2489..0adc8fc 100644 (file)
@@ -1673,15 +1673,11 @@ void testSimplePatchpoint()
     BasicBlock* root = proc.addBlock();
     Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
     Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
-    Value::AdjacencyList children;
-    children.append(arg1);
-    children.append(arg2);
-    PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(
-        proc, Int32, Origin(), WTF::move(children));
-    patchpoint->stackmap.appendConstraint(ValueRep::SomeRegister);
-    patchpoint->stackmap.appendConstraint(ValueRep::SomeRegister);
-    patchpoint->stackmap.setGenerator(
-        [&] (CCallHelpers& jit, const Stackmap::GenerationParams& params) {
+    PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
+    patchpoint->append(ConstrainedValue(arg1, ValueRep::SomeRegister));
+    patchpoint->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
+    patchpoint->setGenerator(
+        [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
             CHECK(params.reps.size() == 3);
             CHECK(params.reps[0].isGPR());
             CHECK(params.reps[1].isGPR());