Title: [195620] trunk/Source/_javascript_Core
Revision
195620
Author
fpi...@apple.com
Date
2016-01-26 14:05:28 -0800 (Tue, 26 Jan 2016)

Log Message

The thing that B3 uses to describe a stack slot should not be a Value
https://bugs.webkit.org/show_bug.cgi?id=153491
rdar://problem/24349446

Reviewed by Geoffrey Garen and Saam Barati.

Prior to this change, B3 represented stack slots by having a StackSlotValue that carried
two meanings:

- It represented a stack slot.

- It was a kind of Value for getting the base of the stack slot.

This seems like a good idea until you consider the following issues.

1) A Value can be killed if it is on an unreachable path, or if it has no effects and
   nobody refers to it. But the FTL uses StackSlotValue to allocate space on the stack.
   When it does this, it doesn't want it to be killed. It will dereference the object, so
   killing it is a bug.

2) A premise of B3 is that it should be always legal to perform the following
   transformation on a value:

   value->replaceWithIdentity(insertionSet.insertValue(index, proc.clone(value)));

   This inserts a new value just before the old one. The new value is a clone of the old
   one. Then the old one is essentially deleted (anything that becomes an identity dies
   shortly thereafter). Problem (1) prevents this from being legal, which breaks a major
   premise of B3 IR.

3) A premise of B3 is that it should be always legal to perform the following
   transformation on a value:

   Before:
           @42 = Thing(...)

   After:
           Branch(@doesntMatter, #yes, #no)
       BB#yes:
           @42_one = Thing(...)
           Upsilon(@42_one, ^42)
           Jump(#done)
       BB#no:
           @42_two = Thing(...)
           Upsilon(@42_two, ^42)
           Jump(#done)
       BB#done:
           @42 = Phi()

   But prior to this change, such a transformation makes absolutely no sense for
   StackSlot. It will "work" in the sense that the compiler will proceed undaunted, but
   it will disable SSA fix-up for the cloned stack slot and we will end up allocating two
   stack slots instead of one, and then we will assume that they both escape, which will
   disable efficient stack allocation. Note that the moral equivalent of this
   transformation could already happen due to tail duplication, and the only reason why
   it's not a bug right now is that we happen to hoist stack slots to the root block. But
   the whole point of our stack slots was supposed to be that they do not have to be
   hoisted.

This change fixes this issue by splitting StackSlotValue into two things: SlotBaseValue,
which is a pure operation for getting the base address of a StackSlot, and StackSlot,
which is a representation of the actual stack slot. StackSlot cannot get duplicated and
can only be killed if it's anonymous. SlotBaseValue can be killed, moved, cloned,
hoisted, etc. Since it has no effects and it has a ValueKey, it's one of the most
permissive Values in the IR, just as one would hope (after all, there is actually zero
code that needs to execute to evaluate SlotBaseValue).

This fixes a crash that we saw with GuardMalloc and ASan. It also makes the IR a lot more
easy to reason about.

* CMakeLists.txt:
* _javascript_Core.xcodeproj/project.pbxproj:
* b3/B3EliminateCommonSubexpressions.cpp:
* b3/B3FixSSA.cpp:
(JSC::B3::demoteValues):
(JSC::B3::fixSSA):
* b3/B3LowerToAir.cpp:
(JSC::B3::Air::LowerToAir::run):
(JSC::B3::Air::LowerToAir::effectiveAddr):
(JSC::B3::Air::LowerToAir::lower):
* b3/B3Opcode.cpp:
(WTF::printInternal):
* b3/B3Opcode.h:
* b3/B3Procedure.cpp:
(JSC::B3::Procedure::setBlockOrderImpl):
(JSC::B3::Procedure::addStackSlot):
(JSC::B3::Procedure::addAnonymousStackSlot):
(JSC::B3::Procedure::clone):
(JSC::B3::Procedure::dump):
(JSC::B3::Procedure::blocksInPostOrder):
(JSC::B3::Procedure::deleteStackSlot):
(JSC::B3::Procedure::deleteValue):
(JSC::B3::Procedure::calleeSaveRegisters):
(JSC::B3::Procedure::addStackSlotIndex):
(JSC::B3::Procedure::addValueIndex):
* b3/B3Procedure.h:
(JSC::B3::Procedure::setBlockOrder):
(JSC::B3::Procedure::StackSlotsCollection::StackSlotsCollection):
(JSC::B3::Procedure::StackSlotsCollection::size):
(JSC::B3::Procedure::StackSlotsCollection::at):
(JSC::B3::Procedure::StackSlotsCollection::operator[]):
(JSC::B3::Procedure::StackSlotsCollection::iterator::iterator):
(JSC::B3::Procedure::StackSlotsCollection::iterator::operator*):
(JSC::B3::Procedure::StackSlotsCollection::iterator::operator++):
(JSC::B3::Procedure::StackSlotsCollection::iterator::operator==):
(JSC::B3::Procedure::StackSlotsCollection::iterator::operator!=):
(JSC::B3::Procedure::StackSlotsCollection::iterator::findNext):
(JSC::B3::Procedure::StackSlotsCollection::begin):
(JSC::B3::Procedure::StackSlotsCollection::end):
(JSC::B3::Procedure::stackSlots):
(JSC::B3::Procedure::ValuesCollection::ValuesCollection):
* b3/B3ReduceStrength.cpp:
* b3/B3SlotBaseValue.cpp: Copied from Source/_javascript_Core/b3/B3StackSlotValue.cpp.
(JSC::B3::SlotBaseValue::~SlotBaseValue):
(JSC::B3::SlotBaseValue::dumpMeta):
(JSC::B3::SlotBaseValue::cloneImpl):
(JSC::B3::StackSlotValue::~StackSlotValue): Deleted.
(JSC::B3::StackSlotValue::dumpMeta): Deleted.
(JSC::B3::StackSlotValue::cloneImpl): Deleted.
* b3/B3SlotBaseValue.h: Copied from Source/_javascript_Core/b3/B3StackSlotValue.h.
* b3/B3StackSlot.cpp: Added.
(JSC::B3::StackSlot::~StackSlot):
(JSC::B3::StackSlot::dump):
(JSC::B3::StackSlot::deepDump):
(JSC::B3::StackSlot::StackSlot):
* b3/B3StackSlot.h: Added.
(JSC::B3::StackSlot::byteSize):
(JSC::B3::StackSlot::kind):
(JSC::B3::StackSlot::isLocked):
(JSC::B3::StackSlot::index):
(JSC::B3::StackSlot::offsetFromFP):
(JSC::B3::StackSlot::setOffsetFromFP):
(JSC::B3::DeepStackSlotDump::DeepStackSlotDump):
(JSC::B3::DeepStackSlotDump::dump):
(JSC::B3::deepDump):
* b3/B3StackSlotValue.cpp: Removed.
* b3/B3StackSlotValue.h: Removed.
* b3/B3Validate.cpp:
* b3/B3Value.cpp:
(JSC::B3::Value::effects):
(JSC::B3::Value::key):
(JSC::B3::Value::checkOpcode):
* b3/B3ValueKey.cpp:
(JSC::B3::ValueKey::materialize):
* b3/air/AirCode.cpp:
(JSC::B3::Air::Code::addBlock):
(JSC::B3::Air::Code::addStackSlot):
(JSC::B3::Air::Code::addSpecial):
* b3/air/AirCode.h:
* b3/air/AirStackSlot.cpp:
(JSC::B3::Air::StackSlot::setOffsetFromFP):
(JSC::B3::Air::StackSlot::dump):
(JSC::B3::Air::StackSlot::deepDump):
(JSC::B3::Air::StackSlot::StackSlot):
* b3/air/AirStackSlot.h:
(JSC::B3::Air::StackSlot::alignment):
(JSC::B3::Air::StackSlot::b3Slot):
(JSC::B3::Air::StackSlot::offsetFromFP):
(WTF::printInternal):
(JSC::B3::Air::StackSlot::value): Deleted.
* b3/testb3.cpp:
(JSC::B3::testStackSlot):
(JSC::B3::testStoreLoadStackSlot):
* ftl/FTLB3Compile.cpp:
* ftl/FTLB3Output.cpp:
(JSC::FTL::Output::appendTo):
(JSC::FTL::Output::lockedStackSlot):
(JSC::FTL::Output::neg):
* ftl/FTLB3Output.h:
(JSC::FTL::Output::framePointer):
(JSC::FTL::Output::constBool):
(JSC::FTL::Output::constInt32):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::lower):
* ftl/FTLState.h:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (195619 => 195620)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2016-01-26 22:05:28 UTC (rev 195620)
@@ -147,11 +147,12 @@
     b3/B3ReduceDoubleToFloat.cpp
     b3/B3ReduceStrength.cpp
     b3/B3SSACalculator.cpp
+    b3/B3SlotBaseValue.cpp
     b3/B3StackmapGenerationParams.cpp
     b3/B3StackmapSpecial.cpp
     b3/B3StackmapValue.cpp
     b3/B3StackSlotKind.cpp
-    b3/B3StackSlotValue.cpp
+    b3/B3StackSlot.cpp
     b3/B3SwitchCase.cpp
     b3/B3SwitchValue.cpp
     b3/B3TimingScope.cpp

Modified: trunk/Source/_javascript_Core/ChangeLog (195619 => 195620)


--- trunk/Source/_javascript_Core/ChangeLog	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-01-26 22:05:28 UTC (rev 195620)
@@ -1,3 +1,181 @@
+2016-01-26  Filip Pizlo  <fpi...@apple.com>
+
+        The thing that B3 uses to describe a stack slot should not be a Value
+        https://bugs.webkit.org/show_bug.cgi?id=153491
+        rdar://problem/24349446
+
+        Reviewed by Geoffrey Garen and Saam Barati.
+
+        Prior to this change, B3 represented stack slots by having a StackSlotValue that carried
+        two meanings:
+
+        - It represented a stack slot.
+
+        - It was a kind of Value for getting the base of the stack slot.
+
+        This seems like a good idea until you consider the following issues.
+
+        1) A Value can be killed if it is on an unreachable path, or if it has no effects and
+           nobody refers to it. But the FTL uses StackSlotValue to allocate space on the stack.
+           When it does this, it doesn't want it to be killed. It will dereference the object, so
+           killing it is a bug.
+
+        2) A premise of B3 is that it should be always legal to perform the following
+           transformation on a value:
+
+           value->replaceWithIdentity(insertionSet.insertValue(index, proc.clone(value)));
+
+           This inserts a new value just before the old one. The new value is a clone of the old
+           one. Then the old one is essentially deleted (anything that becomes an identity dies
+           shortly thereafter). Problem (1) prevents this from being legal, which breaks a major
+           premise of B3 IR.
+
+        3) A premise of B3 is that it should be always legal to perform the following
+           transformation on a value:
+
+           Before:
+                   @42 = Thing(...)
+
+           After:
+                   Branch(@doesntMatter, #yes, #no)
+               BB#yes:
+                   @42_one = Thing(...)
+                   Upsilon(@42_one, ^42)
+                   Jump(#done)
+               BB#no:
+                   @42_two = Thing(...)
+                   Upsilon(@42_two, ^42)
+                   Jump(#done)
+               BB#done:
+                   @42 = Phi()
+
+           But prior to this change, such a transformation makes absolutely no sense for
+           StackSlot. It will "work" in the sense that the compiler will proceed undaunted, but
+           it will disable SSA fix-up for the cloned stack slot and we will end up allocating two
+           stack slots instead of one, and then we will assume that they both escape, which will
+           disable efficient stack allocation. Note that the moral equivalent of this
+           transformation could already happen due to tail duplication, and the only reason why
+           it's not a bug right now is that we happen to hoist stack slots to the root block. But
+           the whole point of our stack slots was supposed to be that they do not have to be
+           hoisted.
+
+        This change fixes this issue by splitting StackSlotValue into two things: SlotBaseValue,
+        which is a pure operation for getting the base address of a StackSlot, and StackSlot,
+        which is a representation of the actual stack slot. StackSlot cannot get duplicated and
+        can only be killed if it's anonymous. SlotBaseValue can be killed, moved, cloned,
+        hoisted, etc. Since it has no effects and it has a ValueKey, it's one of the most
+        permissive Values in the IR, just as one would hope (after all, there is actually zero
+        code that needs to execute to evaluate SlotBaseValue).
+
+        This fixes a crash that we saw with GuardMalloc and ASan. It also makes the IR a lot more
+        easy to reason about.
+
+        * CMakeLists.txt:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * b3/B3EliminateCommonSubexpressions.cpp:
+        * b3/B3FixSSA.cpp:
+        (JSC::B3::demoteValues):
+        (JSC::B3::fixSSA):
+        * b3/B3LowerToAir.cpp:
+        (JSC::B3::Air::LowerToAir::run):
+        (JSC::B3::Air::LowerToAir::effectiveAddr):
+        (JSC::B3::Air::LowerToAir::lower):
+        * b3/B3Opcode.cpp:
+        (WTF::printInternal):
+        * b3/B3Opcode.h:
+        * b3/B3Procedure.cpp:
+        (JSC::B3::Procedure::setBlockOrderImpl):
+        (JSC::B3::Procedure::addStackSlot):
+        (JSC::B3::Procedure::addAnonymousStackSlot):
+        (JSC::B3::Procedure::clone):
+        (JSC::B3::Procedure::dump):
+        (JSC::B3::Procedure::blocksInPostOrder):
+        (JSC::B3::Procedure::deleteStackSlot):
+        (JSC::B3::Procedure::deleteValue):
+        (JSC::B3::Procedure::calleeSaveRegisters):
+        (JSC::B3::Procedure::addStackSlotIndex):
+        (JSC::B3::Procedure::addValueIndex):
+        * b3/B3Procedure.h:
+        (JSC::B3::Procedure::setBlockOrder):
+        (JSC::B3::Procedure::StackSlotsCollection::StackSlotsCollection):
+        (JSC::B3::Procedure::StackSlotsCollection::size):
+        (JSC::B3::Procedure::StackSlotsCollection::at):
+        (JSC::B3::Procedure::StackSlotsCollection::operator[]):
+        (JSC::B3::Procedure::StackSlotsCollection::iterator::iterator):
+        (JSC::B3::Procedure::StackSlotsCollection::iterator::operator*):
+        (JSC::B3::Procedure::StackSlotsCollection::iterator::operator++):
+        (JSC::B3::Procedure::StackSlotsCollection::iterator::operator==):
+        (JSC::B3::Procedure::StackSlotsCollection::iterator::operator!=):
+        (JSC::B3::Procedure::StackSlotsCollection::iterator::findNext):
+        (JSC::B3::Procedure::StackSlotsCollection::begin):
+        (JSC::B3::Procedure::StackSlotsCollection::end):
+        (JSC::B3::Procedure::stackSlots):
+        (JSC::B3::Procedure::ValuesCollection::ValuesCollection):
+        * b3/B3ReduceStrength.cpp:
+        * b3/B3SlotBaseValue.cpp: Copied from Source/_javascript_Core/b3/B3StackSlotValue.cpp.
+        (JSC::B3::SlotBaseValue::~SlotBaseValue):
+        (JSC::B3::SlotBaseValue::dumpMeta):
+        (JSC::B3::SlotBaseValue::cloneImpl):
+        (JSC::B3::StackSlotValue::~StackSlotValue): Deleted.
+        (JSC::B3::StackSlotValue::dumpMeta): Deleted.
+        (JSC::B3::StackSlotValue::cloneImpl): Deleted.
+        * b3/B3SlotBaseValue.h: Copied from Source/_javascript_Core/b3/B3StackSlotValue.h.
+        * b3/B3StackSlot.cpp: Added.
+        (JSC::B3::StackSlot::~StackSlot):
+        (JSC::B3::StackSlot::dump):
+        (JSC::B3::StackSlot::deepDump):
+        (JSC::B3::StackSlot::StackSlot):
+        * b3/B3StackSlot.h: Added.
+        (JSC::B3::StackSlot::byteSize):
+        (JSC::B3::StackSlot::kind):
+        (JSC::B3::StackSlot::isLocked):
+        (JSC::B3::StackSlot::index):
+        (JSC::B3::StackSlot::offsetFromFP):
+        (JSC::B3::StackSlot::setOffsetFromFP):
+        (JSC::B3::DeepStackSlotDump::DeepStackSlotDump):
+        (JSC::B3::DeepStackSlotDump::dump):
+        (JSC::B3::deepDump):
+        * b3/B3StackSlotValue.cpp: Removed.
+        * b3/B3StackSlotValue.h: Removed.
+        * b3/B3Validate.cpp:
+        * b3/B3Value.cpp:
+        (JSC::B3::Value::effects):
+        (JSC::B3::Value::key):
+        (JSC::B3::Value::checkOpcode):
+        * b3/B3ValueKey.cpp:
+        (JSC::B3::ValueKey::materialize):
+        * b3/air/AirCode.cpp:
+        (JSC::B3::Air::Code::addBlock):
+        (JSC::B3::Air::Code::addStackSlot):
+        (JSC::B3::Air::Code::addSpecial):
+        * b3/air/AirCode.h:
+        * b3/air/AirStackSlot.cpp:
+        (JSC::B3::Air::StackSlot::setOffsetFromFP):
+        (JSC::B3::Air::StackSlot::dump):
+        (JSC::B3::Air::StackSlot::deepDump):
+        (JSC::B3::Air::StackSlot::StackSlot):
+        * b3/air/AirStackSlot.h:
+        (JSC::B3::Air::StackSlot::alignment):
+        (JSC::B3::Air::StackSlot::b3Slot):
+        (JSC::B3::Air::StackSlot::offsetFromFP):
+        (WTF::printInternal):
+        (JSC::B3::Air::StackSlot::value): Deleted.
+        * b3/testb3.cpp:
+        (JSC::B3::testStackSlot):
+        (JSC::B3::testStoreLoadStackSlot):
+        * ftl/FTLB3Compile.cpp:
+        * ftl/FTLB3Output.cpp:
+        (JSC::FTL::Output::appendTo):
+        (JSC::FTL::Output::lockedStackSlot):
+        (JSC::FTL::Output::neg):
+        * ftl/FTLB3Output.h:
+        (JSC::FTL::Output::framePointer):
+        (JSC::FTL::Output::constBool):
+        (JSC::FTL::Output::constInt32):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::lower):
+        * ftl/FTLState.h:
+
 2016-01-26  Benjamin Poulain  <benja...@webkit.org>
 
         Remove a useless #include

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (195619 => 195620)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2016-01-26 22:05:28 UTC (rev 195620)
@@ -533,6 +533,8 @@
 		0F9332A514CA7DDD0085F3C6 /* StructureSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F93329B14CA7DC10085F3C6 /* StructureSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F93B4A918B92C4D00178A3F /* PutByIdVariant.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F93B4A718B92C4D00178A3F /* PutByIdVariant.cpp */; };
 		0F93B4AA18B92C4D00178A3F /* PutByIdVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F93B4A818B92C4D00178A3F /* PutByIdVariant.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		0F9495871C57F47500413A48 /* B3StackSlot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9495851C57F47500413A48 /* B3StackSlot.cpp */; };
+		0F9495881C57F47500413A48 /* B3StackSlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9495861C57F47500413A48 /* B3StackSlot.h */; };
 		0F952ABC1B487A7700C367C5 /* TrackedReferences.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F952ABA1B487A7700C367C5 /* TrackedReferences.cpp */; };
 		0F952ABD1B487A7700C367C5 /* TrackedReferences.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F952ABB1B487A7700C367C5 /* TrackedReferences.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -832,8 +834,8 @@
 		0FEC85311BDACDAC0080FF74 /* B3StackmapSpecial.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84E71BDACDAC0080FF74 /* B3StackmapSpecial.h */; };
 		0FEC85321BDACDAC0080FF74 /* B3StackSlotKind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEC84E81BDACDAC0080FF74 /* B3StackSlotKind.cpp */; };
 		0FEC85331BDACDAC0080FF74 /* B3StackSlotKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84E91BDACDAC0080FF74 /* B3StackSlotKind.h */; };
-		0FEC85341BDACDAC0080FF74 /* B3StackSlotValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEC84EA1BDACDAC0080FF74 /* B3StackSlotValue.cpp */; };
-		0FEC85351BDACDAC0080FF74 /* B3StackSlotValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84EB1BDACDAC0080FF74 /* B3StackSlotValue.h */; };
+		0FEC85341BDACDAC0080FF74 /* B3SlotBaseValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEC84EA1BDACDAC0080FF74 /* B3SlotBaseValue.cpp */; };
+		0FEC85351BDACDAC0080FF74 /* B3SlotBaseValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84EB1BDACDAC0080FF74 /* B3SlotBaseValue.h */; };
 		0FEC85361BDACDAC0080FF74 /* B3SuccessorCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84EC1BDACDAC0080FF74 /* B3SuccessorCollection.h */; };
 		0FEC85371BDACDAC0080FF74 /* B3SwitchCase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FEC84ED1BDACDAC0080FF74 /* B3SwitchCase.cpp */; };
 		0FEC85381BDACDAC0080FF74 /* B3SwitchCase.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84EE1BDACDAC0080FF74 /* B3SwitchCase.h */; };
@@ -2715,6 +2717,8 @@
 		0F93329B14CA7DC10085F3C6 /* StructureSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StructureSet.h; sourceTree = "<group>"; };
 		0F93B4A718B92C4D00178A3F /* PutByIdVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PutByIdVariant.cpp; sourceTree = "<group>"; };
 		0F93B4A818B92C4D00178A3F /* PutByIdVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PutByIdVariant.h; sourceTree = "<group>"; };
+		0F9495851C57F47500413A48 /* B3StackSlot.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3StackSlot.cpp; path = b3/B3StackSlot.cpp; sourceTree = "<group>"; };
+		0F9495861C57F47500413A48 /* B3StackSlot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3StackSlot.h; path = b3/B3StackSlot.h; sourceTree = "<group>"; };
 		0F952ABA1B487A7700C367C5 /* TrackedReferences.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrackedReferences.cpp; sourceTree = "<group>"; };
 		0F952ABB1B487A7700C367C5 /* TrackedReferences.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackedReferences.h; sourceTree = "<group>"; };
 		0F963B3613FC6FDE0002D9B2 /* ValueProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValueProfile.h; sourceTree = "<group>"; };
@@ -3028,8 +3032,8 @@
 		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>"; };
 		0FEC84E91BDACDAC0080FF74 /* B3StackSlotKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3StackSlotKind.h; path = b3/B3StackSlotKind.h; sourceTree = "<group>"; };
-		0FEC84EA1BDACDAC0080FF74 /* B3StackSlotValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3StackSlotValue.cpp; path = b3/B3StackSlotValue.cpp; sourceTree = "<group>"; };
-		0FEC84EB1BDACDAC0080FF74 /* B3StackSlotValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3StackSlotValue.h; path = b3/B3StackSlotValue.h; sourceTree = "<group>"; };
+		0FEC84EA1BDACDAC0080FF74 /* B3SlotBaseValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3SlotBaseValue.cpp; path = b3/B3SlotBaseValue.cpp; sourceTree = "<group>"; };
+		0FEC84EB1BDACDAC0080FF74 /* B3SlotBaseValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3SlotBaseValue.h; path = b3/B3SlotBaseValue.h; sourceTree = "<group>"; };
 		0FEC84EC1BDACDAC0080FF74 /* B3SuccessorCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3SuccessorCollection.h; path = b3/B3SuccessorCollection.h; sourceTree = "<group>"; };
 		0FEC84ED1BDACDAC0080FF74 /* B3SwitchCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3SwitchCase.cpp; path = b3/B3SwitchCase.cpp; sourceTree = "<group>"; };
 		0FEC84EE1BDACDAC0080FF74 /* B3SwitchCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3SwitchCase.h; path = b3/B3SwitchCase.h; sourceTree = "<group>"; };
@@ -4853,6 +4857,8 @@
 				43422A651C16221E00E2EB98 /* B3ReduceDoubleToFloat.h */,
 				0FEC85B71BE1462F0080FF74 /* B3ReduceStrength.cpp */,
 				0FEC85B81BE1462F0080FF74 /* B3ReduceStrength.h */,
+				0FEC84EA1BDACDAC0080FF74 /* B3SlotBaseValue.cpp */,
+				0FEC84EB1BDACDAC0080FF74 /* B3SlotBaseValue.h */,
 				0F6B8ADA1C4EFAC300969052 /* B3SSACalculator.cpp */,
 				0F6B8ADB1C4EFAC300969052 /* B3SSACalculator.h */,
 				0F33FCF51C136E2500323F67 /* B3StackmapGenerationParams.cpp */,
@@ -4861,10 +4867,10 @@
 				0FEC84E71BDACDAC0080FF74 /* B3StackmapSpecial.h */,
 				0F338DEF1BE93AD10013C88F /* B3StackmapValue.cpp */,
 				0F338DF01BE93AD10013C88F /* B3StackmapValue.h */,
+				0F9495851C57F47500413A48 /* B3StackSlot.cpp */,
+				0F9495861C57F47500413A48 /* B3StackSlot.h */,
 				0FEC84E81BDACDAC0080FF74 /* B3StackSlotKind.cpp */,
 				0FEC84E91BDACDAC0080FF74 /* B3StackSlotKind.h */,
-				0FEC84EA1BDACDAC0080FF74 /* B3StackSlotValue.cpp */,
-				0FEC84EB1BDACDAC0080FF74 /* B3StackSlotValue.h */,
 				0FEC84EC1BDACDAC0080FF74 /* B3SuccessorCollection.h */,
 				0FEC84ED1BDACDAC0080FF74 /* B3SwitchCase.cpp */,
 				0FEC84EE1BDACDAC0080FF74 /* B3SwitchCase.h */,
@@ -7112,7 +7118,7 @@
 				0FEC85BD1BE1462F0080FF74 /* B3ReduceStrength.h in Headers */,
 				0FEC85311BDACDAC0080FF74 /* B3StackmapSpecial.h in Headers */,
 				0FEC85331BDACDAC0080FF74 /* B3StackSlotKind.h in Headers */,
-				0FEC85351BDACDAC0080FF74 /* B3StackSlotValue.h in Headers */,
+				0FEC85351BDACDAC0080FF74 /* B3SlotBaseValue.h in Headers */,
 				0FEC85361BDACDAC0080FF74 /* B3SuccessorCollection.h in Headers */,
 				0FEC85381BDACDAC0080FF74 /* B3SwitchCase.h in Headers */,
 				0FEC853A1BDACDAC0080FF74 /* B3SwitchValue.h in Headers */,
@@ -7223,6 +7229,7 @@
 				C218D1401655CFD50062BB81 /* CopyWorkList.h in Headers */,
 				C4F4B6F41A05C944005CAB76 /* cpp_generator.py in Headers */,
 				0F338E1C1BF286EA0013C88F /* B3BlockInsertionSet.h in Headers */,
+				0F9495881C57F47500413A48 /* B3StackSlot.h in Headers */,
 				C4F4B6F31A05C944005CAB76 /* cpp_generator_templates.py in Headers */,
 				5DE6E5B30E1728EC00180407 /* create_hash_table in Headers */,
 				9959E92B1BD17FA4001AA413 /* cssmin.py in Headers */,
@@ -8807,7 +8814,7 @@
 				0FEC85BC1BE1462F0080FF74 /* B3ReduceStrength.cpp in Sources */,
 				0FEC85301BDACDAC0080FF74 /* B3StackmapSpecial.cpp in Sources */,
 				0FEC85321BDACDAC0080FF74 /* B3StackSlotKind.cpp in Sources */,
-				0FEC85341BDACDAC0080FF74 /* B3StackSlotValue.cpp in Sources */,
+				0FEC85341BDACDAC0080FF74 /* B3SlotBaseValue.cpp in Sources */,
 				0FEC85371BDACDAC0080FF74 /* B3SwitchCase.cpp in Sources */,
 				0FEC85391BDACDAC0080FF74 /* B3SwitchValue.cpp in Sources */,
 				0F4570401BE584CA0062A629 /* B3TimingScope.cpp in Sources */,
@@ -9033,6 +9040,7 @@
 				0FE254F61ABDDD2200A7C6D2 /* DFGVarargsForwardingPhase.cpp in Sources */,
 				0F6E845A19030BEF00562741 /* DFGVariableAccessData.cpp in Sources */,
 				0FDDBFB51666EED800C55FEF /* DFGVariableAccessDataDump.cpp in Sources */,
+				0F9495871C57F47500413A48 /* B3StackSlot.cpp in Sources */,
 				0F2BDC5115228FFD00CD8910 /* DFGVariableEvent.cpp in Sources */,
 				0F2BDC4A1522809A00CD8910 /* DFGVariableEventStream.cpp in Sources */,
 				0FFFC95F14EF90BB00C72532 /* DFGVirtualRegisterAllocationPhase.cpp in Sources */,

Modified: trunk/Source/_javascript_Core/b3/B3EliminateCommonSubexpressions.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/B3EliminateCommonSubexpressions.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/B3EliminateCommonSubexpressions.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -37,7 +37,8 @@
 #include "B3PhaseScope.h"
 #include "B3ProcedureInlines.h"
 #include "B3PureCSE.h"
-#include "B3StackSlotValue.h"
+#include "B3SlotBaseValue.h"
+#include "B3StackSlot.h"
 #include "B3ValueKey.h"
 #include "B3ValueInlines.h"
 #include "DFGGraph.h"
@@ -130,7 +131,7 @@
             m_impureBlockData[m_block] = m_data;
         }
 
-        for (StackSlotValue* stack : m_stacks)
+        for (SlotBaseValue* stack : m_stacks)
             m_insertionSet.insertValue(0, stack);
         for (BasicBlock* block : m_proc) {
             for (unsigned valueIndex = 0; valueIndex < block->size(); ++valueIndex) {
@@ -369,8 +370,8 @@
         // Right now we're relying on the fact that CSE's position in the phase order is
         // almost right before SSA fixup.
             
-        StackSlotValue* stack = m_proc.add<StackSlotValue>(
-            m_value->origin(), sizeofType(m_value->type()), StackSlotKind::Anonymous);
+        SlotBaseValue* stack = m_proc.add<SlotBaseValue>(
+            m_value->origin(), m_proc.addAnonymousStackSlot(m_value->type()));
         m_stacks.append(stack);
 
         MemoryValue* load = m_insertionSet.insert<MemoryValue>(
@@ -498,7 +499,7 @@
     unsigned m_index;
     Value* m_value;
 
-    Vector<StackSlotValue*> m_stacks;
+    Vector<SlotBaseValue*> m_stacks;
     HashMap<Value*, Vector<Value*>> m_stores;
 
     InsertionSet m_insertionSet;

Modified: trunk/Source/_javascript_Core/b3/B3FixSSA.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/B3FixSSA.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/B3FixSSA.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -38,7 +38,8 @@
 #include "B3PhaseScope.h"
 #include "B3ProcedureInlines.h"
 #include "B3SSACalculator.h"
-#include "B3StackSlotValue.h"
+#include "B3SlotBaseValue.h"
+#include "B3StackSlot.h"
 #include "B3UpsilonValue.h"
 #include "B3ValueInlines.h"
 #include <wtf/CommaPrinter.h>
@@ -51,19 +52,19 @@
 
 void demoteValues(Procedure& proc, const IndexSet<Value>& values)
 {
-    HashMap<Value*, StackSlotValue*> map;
-    HashMap<Value*, StackSlotValue*> phiMap;
+    HashMap<Value*, SlotBaseValue*> map;
+    HashMap<Value*, SlotBaseValue*> phiMap;
 
     // Create stack slots.
     InsertionSet insertionSet(proc);
     for (Value* value : values.values(proc.values())) {
-        StackSlotValue* stack = insertionSet.insert<StackSlotValue>(
-            0, value->origin(), sizeofType(value->type()), StackSlotKind::Anonymous);
+        SlotBaseValue* stack = insertionSet.insert<SlotBaseValue>(
+            0, value->origin(), proc.addAnonymousStackSlot(value->type()));
         map.add(value, stack);
 
         if (value->opcode() == Phi) {
-            StackSlotValue* phiStack = insertionSet.insert<StackSlotValue>(
-                0, value->origin(), sizeofType(value->type()), StackSlotKind::Anonymous);
+            SlotBaseValue* phiStack = insertionSet.insert<SlotBaseValue>(
+                0, value->origin(), proc.addAnonymousStackSlot(value->type()));
             phiMap.add(value, phiStack);
         }
     }
@@ -89,31 +90,31 @@
             Value* value = block->at(valueIndex);
 
             if (value->opcode() == Phi) {
-                if (StackSlotValue* stack = phiMap.get(value)) {
+                if (SlotBaseValue* slotBase = phiMap.get(value)) {
                     value->replaceWithIdentity(
                         insertionSet.insert<MemoryValue>(
-                            valueIndex, Load, value->type(), value->origin(), stack));
+                            valueIndex, Load, value->type(), value->origin(), slotBase));
                 }
             } else {
                 for (Value*& child : value->children()) {
-                    if (StackSlotValue* stack = map.get(child)) {
+                    if (SlotBaseValue* slotBase = map.get(child)) {
                         child = insertionSet.insert<MemoryValue>(
-                            valueIndex, Load, child->type(), value->origin(), stack);
+                            valueIndex, Load, child->type(), value->origin(), slotBase);
                     }
                 }
 
                 if (UpsilonValue* upsilon = value->as<UpsilonValue>()) {
-                    if (StackSlotValue* stack = phiMap.get(upsilon->phi())) {
+                    if (SlotBaseValue* slotBase = phiMap.get(upsilon->phi())) {
                         insertionSet.insert<MemoryValue>(
-                            valueIndex, Store, upsilon->origin(), upsilon->child(0), stack);
+                            valueIndex, Store, upsilon->origin(), upsilon->child(0), slotBase);
                         value->replaceWithNop();
                     }
                 }
             }
 
-            if (StackSlotValue* stack = map.get(value)) {
+            if (SlotBaseValue* slotBase = map.get(value)) {
                 insertionSet.insert<MemoryValue>(
-                    valueIndex + 1, Store, value->origin(), value, stack);
+                    valueIndex + 1, Store, value->origin(), value, slotBase);
             }
         }
         insertionSet.execute(block);
@@ -126,9 +127,10 @@
     
     // Collect the stack "variables". If there aren't any, then we don't have anything to do.
     // That's a fairly common case.
-    HashMap<StackSlotValue*, Type> stackVariable;
+    HashMap<StackSlot*, Type> stackVariable;
     for (Value* value : proc.values()) {
-        if (StackSlotValue* stack = value->as<StackSlotValue>()) {
+        if (SlotBaseValue* slotBase = value->as<SlotBaseValue>()) {
+            StackSlot* stack = slotBase->slot();
             if (stack->kind() == StackSlotKind::Anonymous)
                 stackVariable.add(stack, Void);
         }
@@ -141,14 +143,16 @@
     // Store on anonymous variables.
     for (Value* value : proc.values()) {
         auto reject = [&] (Value* value) {
-            if (StackSlotValue* stack = value->as<StackSlotValue>())
-                stackVariable.remove(stack);
+            if (SlotBaseValue* slotBase = value->as<SlotBaseValue>())
+                stackVariable.remove(slotBase->slot());
         };
         
         auto handleAccess = [&] (Value* access, Type type) {
-            StackSlotValue* stack = access->lastChild()->as<StackSlotValue>();
-            if (!stack)
+            SlotBaseValue* slotBase = access->lastChild()->as<SlotBaseValue>();
+            if (!slotBase)
                 return;
+
+            StackSlot* stack = slotBase->slot();
             
             if (value->as<MemoryValue>()->offset()) {
                 stackVariable.remove(stack);
@@ -184,16 +188,14 @@
         }
     }
 
-    Vector<StackSlotValue*> deadValues;
+    Vector<StackSlot*> deadSlots;
     for (auto& entry : stackVariable) {
         if (entry.value == Void)
-            deadValues.append(entry.key);
+            deadSlots.append(entry.key);
     }
 
-    for (StackSlotValue* deadValue : deadValues) {
-        deadValue->replaceWithNop();
-        stackVariable.remove(deadValue);
-    }
+    for (StackSlot* deadSlot : deadSlots)
+        stackVariable.remove(deadSlot);
 
     if (stackVariable.isEmpty())
         return false;
@@ -204,11 +206,11 @@
     SSACalculator ssa(proc);
 
     // Create a SSACalculator::Variable for every stack variable.
-    Vector<StackSlotValue*> variableToStack;
-    HashMap<StackSlotValue*, SSACalculator::Variable*> stackToVariable;
+    Vector<StackSlot*> variableToStack;
+    HashMap<StackSlot*, SSACalculator::Variable*> stackToVariable;
 
     for (auto& entry : stackVariable) {
-        StackSlotValue* stack = entry.key;
+        StackSlot* stack = entry.key;
         SSACalculator::Variable* variable = ssa.newVariable();
         RELEASE_ASSERT(variable->index() == variableToStack.size());
         variableToStack.append(stack);
@@ -221,10 +223,12 @@
             if (value->opcode() != Store)
                 continue;
 
-            StackSlotValue* stack = value->child(1)->as<StackSlotValue>();
-            if (!stack)
+            SlotBaseValue* slotBase = value->child(1)->as<SlotBaseValue>();
+            if (!slotBase)
                 continue;
 
+            StackSlot* stack = slotBase->slot();
+
             if (SSACalculator::Variable* variable = stackToVariable.get(stack))
                 ssa.newDef(variable, block, value->child(0));
         }
@@ -233,8 +237,8 @@
     // Decide where Phis are to be inserted. This creates them but does not insert them.
     ssa.computePhis(
         [&] (SSACalculator::Variable* variable, BasicBlock* block) -> Value* {
-            StackSlotValue* stack = variableToStack[variable->index()];
-            Value* phi = proc.add<Value>(Phi, stackVariable.get(stack), stack->origin());
+            StackSlot* stack = variableToStack[variable->index()];
+            Value* phi = proc.add<Value>(Phi, stackVariable.get(stack), block->at(0)->origin());
             if (verbose) {
                 dataLog(
                     "Adding Phi for ", pointerDump(stack), " at ", *block, ": ",
@@ -245,12 +249,12 @@
 
     // Now perform the conversion.
     InsertionSet insertionSet(proc);
-    HashMap<StackSlotValue*, Value*> mapping;
+    HashMap<StackSlot*, Value*> mapping;
     for (BasicBlock* block : proc.blocksInPreOrder()) {
         mapping.clear();
 
         for (auto& entry : stackToVariable) {
-            StackSlotValue* stack = entry.key;
+            StackSlot* stack = entry.key;
             SSACalculator::Variable* variable = entry.value;
 
             SSACalculator::Def* def = ssa.reachingDefAtHead(block, variable);
@@ -259,7 +263,7 @@
         }
 
         for (SSACalculator::Def* phiDef : ssa.phisForBlock(block)) {
-            StackSlotValue* stack = variableToStack[phiDef->variable()->index()];
+            StackSlot* stack = variableToStack[phiDef->variable()->index()];
 
             insertionSet.insertValue(0, phiDef->value());
             mapping.set(stack, phiDef->value());
@@ -271,7 +275,8 @@
 
             switch (value->opcode()) {
             case Load: {
-                if (StackSlotValue* stack = value->child(0)->as<StackSlotValue>()) {
+                if (SlotBaseValue* slotBase = value->child(0)->as<SlotBaseValue>()) {
+                    StackSlot* stack = slotBase->slot();
                     if (Value* replacement = mapping.get(stack))
                         value->replaceWithIdentity(replacement);
                 }
@@ -279,7 +284,8 @@
             }
                 
             case Store: {
-                if (StackSlotValue* stack = value->child(1)->as<StackSlotValue>()) {
+                if (SlotBaseValue* slotBase = value->child(1)->as<SlotBaseValue>()) {
+                    StackSlot* stack = slotBase->slot();
                     if (stackToVariable.contains(stack)) {
                         mapping.set(stack, value->child(0));
                         value->replaceWithNop();
@@ -299,7 +305,7 @@
             for (SSACalculator::Def* phiDef : ssa.phisForBlock(successorBlock)) {
                 Value* phi = phiDef->value();
                 SSACalculator::Variable* variable = phiDef->variable();
-                StackSlotValue* stack = variableToStack[variable->index()];
+                StackSlot* stack = variableToStack[variable->index()];
 
                 Value* mappedValue = mapping.get(stack);
                 if (verbose) {
@@ -319,10 +325,6 @@
         insertionSet.execute(block);
     }
 
-    // Finally, kill the stack slots.
-    for (StackSlotValue* stack : variableToStack)
-        stack->replaceWithNop();
-
     if (verbose) {
         dataLog("B3 after SSA conversion:\n");
         dataLog(proc);

Modified: trunk/Source/_javascript_Core/b3/B3LowerToAir.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/B3LowerToAir.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/B3LowerToAir.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -47,7 +47,8 @@
 #include "B3PhaseScope.h"
 #include "B3PhiChildren.h"
 #include "B3Procedure.h"
-#include "B3StackSlotValue.h"
+#include "B3SlotBaseValue.h"
+#include "B3StackSlot.h"
 #include "B3UpsilonValue.h"
 #include "B3UseCounts.h"
 #include "B3ValueInlines.h"
@@ -92,16 +93,14 @@
                     dataLog("Phi tmp for ", *value, ": ", m_phiToTmp[value], "\n");
                 break;
             }
-            case B3::StackSlot: {
-                StackSlotValue* stackSlotValue = value->as<StackSlotValue>();
-                m_stackToStack.add(stackSlotValue, m_code.addStackSlot(stackSlotValue));
-                break;
-            }
             default:
                 break;
             }
         }
 
+        for (B3::StackSlot* stack : m_procedure.stackSlots())
+            m_stackToStack.add(stack, m_code.addStackSlot(stack));
+
         // Figure out which blocks are not rare.
         m_fastWorklist.push(m_procedure[0]);
         while (B3::BasicBlock* block = m_fastWorklist.pop()) {
@@ -433,8 +432,8 @@
         case FramePointer:
             return Arg::addr(Tmp(GPRInfo::callFrameRegister), offset);
 
-        case B3::StackSlot:
-            return Arg::stack(m_stackToStack.get(address->as<StackSlotValue>()), offset);
+        case SlotBase:
+            return Arg::stack(m_stackToStack.get(address->as<SlotBaseValue>()->slot()), offset);
 
         default:
             return fallback();
@@ -1914,10 +1913,10 @@
             return;
         }
 
-        case B3::StackSlot: {
+        case SlotBase: {
             append(
                 Lea,
-                Arg::stack(m_stackToStack.get(m_value->as<StackSlotValue>())),
+                Arg::stack(m_stackToStack.get(m_value->as<SlotBaseValue>()->slot())),
                 tmp(m_value));
             return;
         }
@@ -2284,7 +2283,7 @@
     IndexMap<Value, Tmp> m_valueToTmp; // These are values that must have a Tmp in Air. We say that a Value* with a non-null Tmp is "pinned".
     IndexMap<Value, Tmp> m_phiToTmp; // Each Phi gets its own Tmp.
     IndexMap<B3::BasicBlock, Air::BasicBlock*> m_blockToBlock;
-    HashMap<StackSlotValue*, Air::StackSlot*> m_stackToStack;
+    HashMap<B3::StackSlot*, Air::StackSlot*> m_stackToStack;
 
     UseCounts m_useCounts;
     PhiChildren m_phiChildren;

Modified: trunk/Source/_javascript_Core/b3/B3Opcode.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/B3Opcode.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/B3Opcode.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -95,8 +95,8 @@
     case ConstFloat:
         out.print("ConstFloat");
         return;
-    case StackSlot:
-        out.print("StackSlot");
+    case SlotBase:
+        out.print("SlotBase");
         return;
     case ArgumentReg:
         out.print("ArgumentReg");

Modified: trunk/Source/_javascript_Core/b3/B3Opcode.h (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/B3Opcode.h	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/B3Opcode.h	2016-01-26 22:05:28 UTC (rev 195620)
@@ -51,7 +51,7 @@
     // The magical stack slot. This is viewed as executing at the top of the program regardless of
     // where in control flow you put it. Each instance of a StackSlot Value gets a disjoint range of
     // stack memory. Use the StackSlotValue class.
-    StackSlot,
+    SlotBase,
 
     // The magical argument register. This is viewed as executing at the top of the program
     // regardless of where in control flow you put it, and the compiler takes care to ensure that we

Modified: trunk/Source/_javascript_Core/b3/B3Procedure.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/B3Procedure.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/B3Procedure.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -36,6 +36,7 @@
 #include "B3DataSection.h"
 #include "B3Dominators.h"
 #include "B3OpaqueByproducts.h"
+#include "B3StackSlot.h"
 #include "B3ValueInlines.h"
 
 namespace JSC { namespace B3 {
@@ -91,6 +92,20 @@
     }
 }
 
+StackSlot* Procedure::addStackSlot(unsigned byteSize, StackSlotKind kind)
+{
+    size_t index = addStackSlotIndex();
+    std::unique_ptr<StackSlot> slot(new StackSlot(index, byteSize, kind));
+    StackSlot* result = slot.get();
+    m_stackSlots[index] = WTFMove(slot);
+    return result;
+}
+
+StackSlot* Procedure::addAnonymousStackSlot(Type type)
+{
+    return addStackSlot(sizeofType(type), StackSlotKind::Anonymous);
+}
+
 Value* Procedure::clone(Value* value)
 {
     std::unique_ptr<Value> clone(value->cloneImpl());
@@ -192,6 +207,11 @@
         }
         dataLog("    ", deepDump(*this, value), "\n");
     }
+    if (stackSlots().size()) {
+        out.print("Stack slots:\n");
+        for (StackSlot* slot : stackSlots())
+            out.print("    ", pointerDump(slot), ": ", deepDump(slot), "\n");
+    }
     if (m_byproducts->count())
         out.print(*m_byproducts);
 }
@@ -206,6 +226,14 @@
     return B3::blocksInPostOrder(at(0));
 }
 
+void Procedure::deleteStackSlot(StackSlot* stackSlot)
+{
+    RELEASE_ASSERT(m_stackSlots[stackSlot->index()].get() == stackSlot);
+    RELEASE_ASSERT(!stackSlot->isLocked());
+    m_stackSlotIndexFreeList.append(stackSlot->index());
+    m_stackSlots[stackSlot->index()] = nullptr;
+}
+
 void Procedure::deleteValue(Value* value)
 {
     RELEASE_ASSERT(m_values[value->index()].get() == value);
@@ -282,6 +310,17 @@
     return code().calleeSaveRegisters();
 }
 
+size_t Procedure::addStackSlotIndex()
+{
+    if (m_stackSlotIndexFreeList.isEmpty()) {
+        size_t index = m_stackSlots.size();
+        m_stackSlots.append(nullptr);
+        return index;
+    }
+    
+    return m_stackSlotIndexFreeList.takeLast();
+}
+
 size_t Procedure::addValueIndex()
 {
     if (m_valueIndexFreeList.isEmpty()) {

Modified: trunk/Source/_javascript_Core/b3/B3Procedure.h (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/B3Procedure.h	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/B3Procedure.h	2016-01-26 22:05:28 UTC (rev 195620)
@@ -30,6 +30,7 @@
 
 #include "B3OpaqueByproducts.h"
 #include "B3Origin.h"
+#include "B3StackSlotKind.h"
 #include "B3Type.h"
 #include "B3ValueKey.h"
 #include "PureNaN.h"
@@ -49,6 +50,7 @@
 class BlockInsertionSet;
 class CFG;
 class Dominators;
+class StackSlot;
 class Value;
 
 namespace Air { class Code; }
@@ -90,6 +92,9 @@
             blocks.append(block);
         setBlockOrderImpl(blocks);
     }
+
+    JS_EXPORT_PRIVATE StackSlot* addStackSlot(unsigned byteSize, StackSlotKind);
+    JS_EXPORT_PRIVATE StackSlot* addAnonymousStackSlot(Type);
     
     template<typename ValueType, typename... Arguments>
     ValueType* add(Arguments...);
@@ -172,6 +177,75 @@
     Vector<BasicBlock*> blocksInPreOrder();
     Vector<BasicBlock*> blocksInPostOrder();
 
+    class StackSlotsCollection {
+    public:
+        StackSlotsCollection(const Procedure& proc)
+            : m_proc(proc)
+        {
+        }
+
+        unsigned size() const { return m_proc.m_stackSlots.size(); }
+        StackSlot* at(unsigned index) const { return m_proc.m_stackSlots[index].get(); }
+        StackSlot* operator[](unsigned index) const { return at(index); }
+
+        class iterator {
+        public:
+            iterator()
+                : m_collection(nullptr)
+                , m_index(0)
+            {
+            }
+
+            iterator(const StackSlotsCollection& collection, unsigned index)
+                : m_collection(&collection)
+                , m_index(findNext(index))
+            {
+            }
+
+            StackSlot* operator*()
+            {
+                return m_collection->at(m_index);
+            }
+
+            iterator& operator++()
+            {
+                m_index = findNext(m_index + 1);
+                return *this;
+            }
+
+            bool operator==(const iterator& other) const
+            {
+                return m_index == other.m_index;
+            }
+
+            bool operator!=(const iterator& other) const
+            {
+                return !(*this == other);
+            }
+
+        private:
+            unsigned findNext(unsigned index)
+            {
+                while (index < m_collection->size() && !m_collection->at(index))
+                    index++;
+                return index;
+            }
+            
+            const StackSlotsCollection* m_collection;
+            unsigned m_index;
+        };
+
+        iterator begin() const { return iterator(*this, 0); }
+        iterator end() const { return iterator(*this, size()); }
+
+    private:
+        const Procedure& m_proc;
+    };
+
+    StackSlotsCollection stackSlots() const { return StackSlotsCollection(*this); }
+
+    void deleteStackSlot(StackSlot*);
+    
     class ValuesCollection {
     public:
         ValuesCollection(const Procedure& procedure)
@@ -292,10 +366,13 @@
     
     void setBlockOrderImpl(Vector<BasicBlock*>&);
 
+    size_t addStackSlotIndex();
     JS_EXPORT_PRIVATE size_t addValueIndex();
-    
+
+    Vector<std::unique_ptr<StackSlot>> m_stackSlots;
     Vector<std::unique_ptr<BasicBlock>> m_blocks;
     Vector<std::unique_ptr<Value>> m_values;
+    Vector<size_t> m_stackSlotIndexFreeList;
     Vector<size_t> m_valueIndexFreeList;
     std::unique_ptr<CFG> m_cfg;
     std::unique_ptr<Dominators> m_dominators;

Modified: trunk/Source/_javascript_Core/b3/B3ReduceStrength.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/B3ReduceStrength.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/B3ReduceStrength.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -40,6 +40,8 @@
 #include "B3PhiChildren.h"
 #include "B3ProcedureInlines.h"
 #include "B3PureCSE.h"
+#include "B3SlotBaseValue.h"
+#include "B3StackSlot.h"
 #include "B3UpsilonValue.h"
 #include "B3ValueKeyInlines.h"
 #include "B3ValueInlines.h"
@@ -2075,14 +2077,18 @@
                 break;
         }
 
+        IndexSet<StackSlot> liveStackSlots;
+        
         for (BasicBlock* block : m_proc) {
             size_t sourceIndex = 0;
             size_t targetIndex = 0;
             while (sourceIndex < block->size()) {
                 Value* value = block->at(sourceIndex++);
-                if (worklist.saw(value))
+                if (worklist.saw(value)) {
+                    if (SlotBaseValue* slotBase = value->as<SlotBaseValue>())
+                        liveStackSlots.add(slotBase->slot());
                     block->at(targetIndex++) = value;
-                else {
+                } else {
                     m_proc.deleteValue(value);
                     
                     // It's not entirely clear if this is needed. I think it makes sense to have
@@ -2094,6 +2100,12 @@
             }
             block->values().resize(targetIndex);
         }
+
+        for (StackSlot* slot : m_proc.stackSlots()) {
+            if (slot->isLocked() || liveStackSlots.contains(slot))
+                continue;
+            m_proc.deleteStackSlot(slot);
+        }
     }
 
     void simplifySSA()

Copied: trunk/Source/_javascript_Core/b3/B3SlotBaseValue.cpp (from rev 195584, trunk/Source/_javascript_Core/b3/B3StackSlotValue.cpp) (0 => 195620)


--- trunk/Source/_javascript_Core/b3/B3SlotBaseValue.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/b3/B3SlotBaseValue.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2015-2016 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 "B3SlotBaseValue.h"
+
+#if ENABLE(B3_JIT)
+
+#include "B3StackSlot.h"
+
+namespace JSC { namespace B3 {
+
+SlotBaseValue::~SlotBaseValue()
+{
+}
+
+void SlotBaseValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
+{
+    out.print(comma, pointerDump(m_slot));
+}
+
+Value* SlotBaseValue::cloneImpl() const
+{
+    return new SlotBaseValue(*this);
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)

Copied: trunk/Source/_javascript_Core/b3/B3SlotBaseValue.h (from rev 195584, trunk/Source/_javascript_Core/b3/B3StackSlotValue.h) (0 => 195620)


--- trunk/Source/_javascript_Core/b3/B3SlotBaseValue.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/b3/B3SlotBaseValue.h	2016-01-26 22:05:28 UTC (rev 195620)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015-2016 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 B3SlotBaseValue_h
+#define B3SlotBaseValue_h
+
+#if ENABLE(B3_JIT)
+
+#include "B3Value.h"
+
+namespace JSC { namespace B3 {
+
+class StackSlot;
+
+class JS_EXPORT_PRIVATE SlotBaseValue : public Value {
+public:
+    static bool accepts(Opcode opcode) { return opcode == SlotBase; }
+
+    ~SlotBaseValue();
+
+    StackSlot* slot() const { return m_slot; }
+
+protected:
+    void dumpMeta(CommaPrinter&, PrintStream&) const override;
+
+    Value* cloneImpl() const override;
+
+private:
+    friend class Procedure;
+
+    SlotBaseValue(unsigned index, Origin origin, StackSlot* slot)
+        : Value(index, CheckedOpcode, SlotBase, pointerType(), origin)
+        , m_slot(slot)
+    {
+    }
+
+    StackSlot* m_slot;
+};
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3SlotBaseValue_h
+

Added: trunk/Source/_javascript_Core/b3/B3StackSlot.cpp (0 => 195620)


--- trunk/Source/_javascript_Core/b3/B3StackSlot.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/b3/B3StackSlot.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 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 "B3StackSlot.h"
+
+#if ENABLE(B3_JIT)
+
+namespace JSC { namespace B3 {
+
+StackSlot::~StackSlot()
+{
+}
+
+void StackSlot::dump(PrintStream& out) const
+{
+    out.print("stack", m_index);
+}
+
+void StackSlot::deepDump(PrintStream& out) const
+{
+    out.print("byteSize = ", m_byteSize, ", offsetFromFP = ", m_offsetFromFP, ", kind = ", m_kind);
+}
+
+StackSlot::StackSlot(unsigned index, unsigned byteSize, StackSlotKind kind)
+    : m_index(index)
+    , m_byteSize(byteSize)
+    , m_kind(kind)
+{
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+

Added: trunk/Source/_javascript_Core/b3/B3StackSlot.h (0 => 195620)


--- trunk/Source/_javascript_Core/b3/B3StackSlot.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/b3/B3StackSlot.h	2016-01-26 22:05:28 UTC (rev 195620)
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2016 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 B3StackSlot_h
+#define B3StackSlot_h
+
+#if ENABLE(B3_JIT)
+
+#include "B3StackSlotKind.h"
+#include <wtf/FastMalloc.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/PrintStream.h>
+
+namespace JSC { namespace B3 {
+
+class Procedure;
+
+namespace Air {
+class StackSlot;
+} // namespace Air
+
+class StackSlot {
+    WTF_MAKE_NONCOPYABLE(StackSlot);
+    WTF_MAKE_FAST_ALLOCATED;
+
+public:
+    ~StackSlot();
+
+    unsigned byteSize() const { return m_byteSize; }
+    StackSlotKind kind() const { return m_kind; }
+    bool isLocked() const { return m_kind == StackSlotKind::Locked; }
+    unsigned index() const { return m_index; }
+
+    // This gets assigned at the end of compilation. But, you can totally pin stack slots. Use the
+    // set method to do that.
+    intptr_t offsetFromFP() const { return m_offsetFromFP; }
+
+    // Note that this is meaningless unless the stack slot is Locked.
+    void setOffsetFromFP(intptr_t value)
+    {
+        m_offsetFromFP = value;
+    }
+
+    void dump(PrintStream& out) const;
+    void deepDump(PrintStream&) const;
+
+private:
+    friend class Air::StackSlot;
+    friend class Procedure;
+
+    StackSlot(unsigned index, unsigned byteSize, StackSlotKind);
+
+    unsigned m_index;
+    unsigned m_byteSize;
+    StackSlotKind m_kind;
+    intptr_t m_offsetFromFP { 0 };
+};
+
+class DeepStackSlotDump {
+public:
+    DeepStackSlotDump(const StackSlot* slot)
+        : m_slot(slot)
+    {
+    }
+
+    void dump(PrintStream& out) const
+    {
+        if (m_slot)
+            m_slot->deepDump(out);
+        else
+            out.print("<null>");
+    }
+
+private:
+    const StackSlot* m_slot;
+};
+
+inline DeepStackSlotDump deepDump(const StackSlot* slot)
+{
+    return DeepStackSlotDump(slot);
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3StackSlot_h
+

Deleted: trunk/Source/_javascript_Core/b3/B3StackSlotValue.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/B3StackSlotValue.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/B3StackSlotValue.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2015-2016 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 "B3StackSlotValue.h"
-
-#if ENABLE(B3_JIT)
-
-namespace JSC { namespace B3 {
-
-StackSlotValue::~StackSlotValue()
-{
-}
-
-void StackSlotValue::dumpMeta(CommaPrinter& comma, PrintStream& out) const
-{
-    out.print(comma, "byteSize = ", m_byteSize, ", kind = ", m_kind);
-}
-
-Value* StackSlotValue::cloneImpl() const
-{
-    return new StackSlotValue(*this);
-}
-
-} } // namespace JSC::B3
-
-#endif // ENABLE(B3_JIT)

Deleted: trunk/Source/_javascript_Core/b3/B3StackSlotValue.h (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/B3StackSlotValue.h	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/B3StackSlotValue.h	2016-01-26 22:05:28 UTC (rev 195620)
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2015-2016 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 B3StackSlotValue_h
-#define B3StackSlotValue_h
-
-#if ENABLE(B3_JIT)
-
-#include "B3StackSlotKind.h"
-#include "B3Value.h"
-
-namespace JSC { namespace B3 {
-
-namespace Air {
-class StackSlot;
-} // namespace Air
-
-class JS_EXPORT_PRIVATE StackSlotValue : public Value {
-public:
-    static bool accepts(Opcode opcode) { return opcode == StackSlot; }
-
-    ~StackSlotValue();
-
-    unsigned byteSize() const { return m_byteSize; }
-    StackSlotKind kind() const { return m_kind; }
-
-    // This gets assigned at the end of compilation. But, you can totally pin stack slots. Use the
-    // set method to do that.
-    intptr_t offsetFromFP() const { return m_offsetFromFP; }
-
-    // Note that this is meaningless unless the stack slot is Locked.
-    void setOffsetFromFP(intptr_t value)
-    {
-        m_offsetFromFP = value;
-    }
-
-protected:
-    void dumpMeta(CommaPrinter&, PrintStream&) const override;
-
-    Value* cloneImpl() const override;
-
-private:
-    friend class Air::StackSlot;
-    friend class Procedure;
-
-    StackSlotValue(unsigned index, Origin origin, unsigned byteSize, StackSlotKind kind)
-        : Value(index, CheckedOpcode, StackSlot, pointerType(), origin)
-        , m_byteSize(byteSize)
-        , m_kind(kind)
-        , m_offsetFromFP(0)
-    {
-    }
-
-    unsigned m_byteSize;
-    StackSlotKind m_kind;
-    intptr_t m_offsetFromFP;
-};
-
-} } // namespace JSC::B3
-
-#endif // ENABLE(B3_JIT)
-
-#endif // B3StackSlotValue_h
-

Modified: trunk/Source/_javascript_Core/b3/B3Validate.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/B3Validate.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/B3Validate.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -33,7 +33,8 @@
 #include "B3Dominators.h"
 #include "B3MemoryValue.h"
 #include "B3Procedure.h"
-#include "B3StackSlotValue.h"
+#include "B3SlotBaseValue.h"
+#include "B3StackSlot.h"
 #include "B3UpsilonValue.h"
 #include "B3ValueInlines.h"
 #include <wtf/HashSet.h>
@@ -152,7 +153,7 @@
                 VALIDATE(!value->numChildren(), ("At ", *value));
                 VALIDATE(value->type() == Float, ("At ", *value));
                 break;
-            case StackSlot:
+            case SlotBase:
             case FramePointer:
                 VALIDATE(!value->numChildren(), ("At ", *value));
                 VALIDATE(value->type() == pointerType(), ("At ", *value));
@@ -410,10 +411,12 @@
     void validateStackAccess(Value* value)
     {
         MemoryValue* memory = value->as<MemoryValue>();
-        StackSlotValue* stack = value->lastChild()->as<StackSlotValue>();
-        if (!stack)
+        SlotBaseValue* slotBase = value->lastChild()->as<SlotBaseValue>();
+        if (!slotBase)
             return;
 
+        StackSlot* stack = slotBase->slot();
+
         VALIDATE(memory->offset() >= 0, ("At ", *value));
         VALIDATE(memory->offset() + memory->accessByteSize() <= stack->byteSize(), ("At ", *value));
     }

Modified: trunk/Source/_javascript_Core/b3/B3Value.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/B3Value.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/B3Value.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -34,7 +34,8 @@
 #include "B3MemoryValue.h"
 #include "B3OriginDump.h"
 #include "B3ProcedureInlines.h"
-#include "B3StackSlotValue.h"
+#include "B3SlotBaseValue.h"
+#include "B3StackSlot.h"
 #include "B3UpsilonValue.h"
 #include "B3ValueInlines.h"
 #include "B3ValueKeyInlines.h"
@@ -383,7 +384,7 @@
     case Const64:
     case ConstDouble:
     case ConstFloat:
-    case StackSlot:
+    case SlotBase:
     case ArgumentReg:
     case FramePointer:
     case Add:
@@ -535,6 +536,10 @@
         return ValueKey(
             ArgumentReg, type(),
             static_cast<int64_t>(as<ArgumentRegValue>()->argumentReg().index()));
+    case SlotBase:
+        return ValueKey(
+            SlotBase, type(),
+            static_cast<int64_t>(as<SlotBaseValue>()->slot()->index()));
     default:
         return ValueKey();
     }
@@ -565,7 +570,7 @@
     ASSERT(!ControlValue::accepts(opcode));
     ASSERT(!MemoryValue::accepts(opcode));
     ASSERT(!PatchpointValue::accepts(opcode));
-    ASSERT(!StackSlotValue::accepts(opcode));
+    ASSERT(!SlotBaseValue::accepts(opcode));
     ASSERT(!UpsilonValue::accepts(opcode));
 }
 #endif // !ASSERT_DISABLED

Modified: trunk/Source/_javascript_Core/b3/B3ValueKey.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/B3ValueKey.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/B3ValueKey.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -30,6 +30,7 @@
 
 #include "B3ArgumentRegValue.h"
 #include "B3ProcedureInlines.h"
+#include "B3SlotBaseValue.h"
 #include "B3ValueInlines.h"
 #include "B3ValueKeyInlines.h"
 
@@ -104,6 +105,8 @@
         return proc.add<ConstFloatValue>(origin, floatValue());
     case ArgumentReg:
         return proc.add<ArgumentRegValue>(origin, Reg::fromIndex(static_cast<unsigned>(value())));
+    case SlotBase:
+        return proc.add<SlotBaseValue>(origin, proc.stackSlots()[value()]);
     default:
         return nullptr;
     }

Modified: trunk/Source/_javascript_Core/b3/air/AirCode.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/air/AirCode.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/air/AirCode.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
 
 #include "AirCCallSpecial.h"
 #include "B3BasicBlockUtils.h"
-#include "B3StackSlotValue.h"
+#include "B3StackSlot.h"
 
 namespace JSC { namespace B3 { namespace Air {
 
@@ -52,17 +52,17 @@
     return result;
 }
 
-StackSlot* Code::addStackSlot(unsigned byteSize, StackSlotKind kind, StackSlotValue* value)
+StackSlot* Code::addStackSlot(unsigned byteSize, StackSlotKind kind, B3::StackSlot* b3Slot)
 {
-    std::unique_ptr<StackSlot> slot(new StackSlot(byteSize, m_stackSlots.size(), kind, value));
+    std::unique_ptr<StackSlot> slot(new StackSlot(byteSize, m_stackSlots.size(), kind, b3Slot));
     StackSlot* result = slot.get();
     m_stackSlots.append(WTFMove(slot));
     return result;
 }
 
-StackSlot* Code::addStackSlot(StackSlotValue* value)
+StackSlot* Code::addStackSlot(B3::StackSlot* b3Slot)
 {
-    return addStackSlot(value->byteSize(), value->kind(), value);
+    return addStackSlot(b3Slot->byteSize(), b3Slot->kind(), b3Slot);
 }
 
 Special* Code::addSpecial(std::unique_ptr<Special> special)

Modified: trunk/Source/_javascript_Core/b3/air/AirCode.h (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/air/AirCode.h	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/air/AirCode.h	2016-01-26 22:05:28 UTC (rev 195620)
@@ -68,8 +68,8 @@
     // of any prior stack slot. In fact, all stack slots you create in the future will have an index
     // that is >= stackSlots().size().
     JS_EXPORT_PRIVATE StackSlot* addStackSlot(
-        unsigned byteSize, StackSlotKind, StackSlotValue* = nullptr);
-    StackSlot* addStackSlot(StackSlotValue*);
+        unsigned byteSize, StackSlotKind, B3::StackSlot* = nullptr);
+    StackSlot* addStackSlot(B3::StackSlot*);
 
     Special* addSpecial(std::unique_ptr<Special>);
 

Modified: trunk/Source/_javascript_Core/b3/air/AirStackSlot.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/air/AirStackSlot.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/air/AirStackSlot.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,15 +28,15 @@
 
 #if ENABLE(B3_JIT)
 
-#include "B3StackSlotValue.h"
+#include "B3StackSlot.h"
 
 namespace JSC { namespace B3 { namespace Air {
 
 void StackSlot::setOffsetFromFP(intptr_t value)
 {
     m_offsetFromFP = value;
-    if (m_value)
-        m_value->m_offsetFromFP = value;
+    if (m_b3Slot)
+        m_b3Slot->m_offsetFromFP = value;
 }
 
 void StackSlot::dump(PrintStream& out) const
@@ -47,16 +47,16 @@
 void StackSlot::deepDump(PrintStream& out) const
 {
     out.print("byteSize = ", m_byteSize, ", offsetFromFP = ", m_offsetFromFP, ", kind = ", m_kind);
-    if (m_value)
-        out.print(", value = ", *m_value);
+    if (m_b3Slot)
+        out.print(", b3Slot = ", *m_b3Slot, ": (", B3::deepDump(m_b3Slot), ")");
 }
 
-StackSlot::StackSlot(unsigned byteSize, unsigned index, StackSlotKind kind, StackSlotValue* value)
+StackSlot::StackSlot(unsigned byteSize, unsigned index, StackSlotKind kind, B3::StackSlot* b3Slot)
     : m_byteSize(byteSize)
     , m_index(index)
-    , m_offsetFromFP(value ? value->offsetFromFP() : 0)
+    , m_offsetFromFP(b3Slot ? b3Slot->offsetFromFP() : 0)
     , m_kind(kind)
-    , m_value(value)
+    , m_b3Slot(b3Slot)
 {
     ASSERT(byteSize);
 }

Modified: trunk/Source/_javascript_Core/b3/air/AirStackSlot.h (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/air/AirStackSlot.h	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/air/AirStackSlot.h	2016-01-26 22:05:28 UTC (rev 195620)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,7 +35,7 @@
 
 namespace JSC { namespace B3 {
 
-class StackSlotValue;
+class StackSlot;
 
 namespace Air {
 
@@ -65,7 +65,7 @@
         return 8;
     }
 
-    StackSlotValue* value() const { return m_value; }
+    B3::StackSlot* b3Slot() const { return m_b3Slot; }
 
     // Zero means that it's not yet assigned.
     intptr_t offsetFromFP() const { return m_offsetFromFP; }
@@ -80,13 +80,13 @@
 private:
     friend class Code;
 
-    StackSlot(unsigned byteSize, unsigned index, StackSlotKind, StackSlotValue*);
+    StackSlot(unsigned byteSize, unsigned index, StackSlotKind, B3::StackSlot*);
     
     unsigned m_byteSize;
     unsigned m_index;
     intptr_t m_offsetFromFP;
     StackSlotKind m_kind;
-    StackSlotValue* m_value;
+    B3::StackSlot* m_b3Slot;
 };
 
 class DeepStackSlotDump {
@@ -119,7 +119,7 @@
 
 inline void printInternal(PrintStream& out, JSC::B3::Air::StackSlot* stackSlot)
 {
-    out.print(*stackSlot);
+    out.print(pointerDump(stackSlot));
 }
 
 } // namespace WTF

Modified: trunk/Source/_javascript_Core/b3/testb3.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/b3/testb3.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/b3/testb3.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -37,7 +37,8 @@
 #include "B3MathExtras.h"
 #include "B3MemoryValue.h"
 #include "B3Procedure.h"
-#include "B3StackSlotValue.h"
+#include "B3SlotBaseValue.h"
+#include "B3StackSlot.h"
 #include "B3StackmapGenerationParams.h"
 #include "B3SwitchValue.h"
 #include "B3UpsilonValue.h"
@@ -4987,7 +4988,8 @@
     BasicBlock* root = proc.addBlock();
     root->appendNew<ControlValue>(
         proc, Return, Origin(),
-        root->appendNew<StackSlotValue>(proc, Origin(), 1, StackSlotKind::Anonymous));
+        root->appendNew<SlotBaseValue>(
+            proc, Origin(), proc.addStackSlot(1, StackSlotKind::Anonymous)));
 
     void* stackSlot = compileAndRun<void*>(proc);
     CHECK(stackSlot < &proc);
@@ -5015,8 +5017,8 @@
     Procedure proc;
     BasicBlock* root = proc.addBlock();
 
-    StackSlotValue* stack = root->appendNew<StackSlotValue>(
-        proc, Origin(), sizeof(int), StackSlotKind::Anonymous);
+    SlotBaseValue* stack = root->appendNew<SlotBaseValue>(
+        proc, Origin(), proc.addStackSlot(sizeof(int), StackSlotKind::Anonymous));
 
     root->appendNew<MemoryValue>(
         proc, Store, Origin(),

Modified: trunk/Source/_javascript_Core/ftl/FTLB3Compile.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/ftl/FTLB3Compile.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/ftl/FTLB3Compile.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -31,7 +31,7 @@
 #include "AirCode.h"
 #include "B3Generate.h"
 #include "B3ProcedureInlines.h"
-#include "B3StackSlotValue.h"
+#include "B3StackSlot.h"
 #include "CodeBlockWithJITType.h"
 #include "CCallHelpers.h"
 #include "DFGCommon.h"
@@ -84,6 +84,12 @@
 
     int localsOffset =
         state.capturedValue->offsetFromFP() / sizeof(EncodedJSValue) + graph.m_nextMachineLocal;
+    if (shouldDumpDisassembly()) {
+        dataLog(
+            "localsOffset = ", localsOffset, " for stack slot: ",
+            pointerDump(state.capturedValue), " at ", RawPointer(state.capturedValue), "\n");
+    }
+    
     for (unsigned i = graph.m_inlineVariableData.size(); i--;) {
         InlineCallFrame* inlineCallFrame = graph.m_inlineVariableData[i].inlineCallFrame;
         

Modified: trunk/Source/_javascript_Core/ftl/FTLB3Output.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/ftl/FTLB3Output.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/ftl/FTLB3Output.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -79,9 +79,10 @@
     m_block = block;
 }
 
-StackSlotValue* Output::lockedStackSlot(size_t bytes)
+SlotBaseValue* Output::lockedStackSlot(size_t bytes)
 {
-    return m_block->appendNew<StackSlotValue>(m_proc, origin(), bytes, StackSlotKind::Locked);
+    return m_block->appendNew<SlotBaseValue>(
+        m_proc, origin(), m_proc.addStackSlot(bytes, StackSlotKind::Locked));
 }
 
 LValue Output::neg(LValue value)

Modified: trunk/Source/_javascript_Core/ftl/FTLB3Output.h (195619 => 195620)


--- trunk/Source/_javascript_Core/ftl/FTLB3Output.h	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/ftl/FTLB3Output.h	2016-01-26 22:05:28 UTC (rev 195620)
@@ -40,7 +40,7 @@
 #include "B3ControlValue.h"
 #include "B3MemoryValue.h"
 #include "B3Procedure.h"
-#include "B3StackSlotValue.h"
+#include "B3SlotBaseValue.h"
 #include "B3SwitchValue.h"
 #include "B3UpsilonValue.h"
 #include "B3ValueInlines.h"
@@ -102,7 +102,7 @@
 
     LValue framePointer() { return m_block->appendNew<B3::Value>(m_proc, B3::FramePointer, origin()); }
 
-    B3::StackSlotValue* lockedStackSlot(size_t bytes);
+    B3::SlotBaseValue* lockedStackSlot(size_t bytes);
 
     LValue constBool(bool value) { return m_block->appendNew<B3::Const32Value>(m_proc, origin(), value); }
     LValue constInt32(int32_t value) { return m_block->appendNew<B3::Const32Value>(m_proc, origin(), value); }

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (195619 => 195620)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2016-01-26 22:05:28 UTC (rev 195620)
@@ -207,9 +207,9 @@
 
 #if FTL_USES_B3
         size_t sizeOfCaptured = sizeof(JSValue) * m_graph.m_nextMachineLocal;
-        B3::StackSlotValue* capturedBase = m_out.lockedStackSlot(sizeOfCaptured);
+        B3::SlotBaseValue* capturedBase = m_out.lockedStackSlot(sizeOfCaptured);
         m_captured = m_out.add(capturedBase, m_out.constIntPtr(sizeOfCaptured));
-        state->capturedValue = capturedBase;
+        state->capturedValue = capturedBase->slot();
 #else // FTL_USES_B3
         LValue capturedAlloca = m_out.alloca(arrayType(m_out.int64, m_graph.m_nextMachineLocal));
         

Modified: trunk/Source/_javascript_Core/ftl/FTLState.h (195619 => 195620)


--- trunk/Source/_javascript_Core/ftl/FTLState.h	2016-01-26 21:55:08 UTC (rev 195619)
+++ trunk/Source/_javascript_Core/ftl/FTLState.h	2016-01-26 22:05:28 UTC (rev 195620)
@@ -47,7 +47,7 @@
 
 namespace B3 {
 class PatchpointValue;
-class StackSlotValue;
+class StackSlot;
 } // namespace B3
 
 namespace FTL {
@@ -89,7 +89,7 @@
     // are no applicable catch blocks anywhere in the Graph.
     RefPtr<PatchpointExceptionHandle> defaultExceptionHandle;
     Box<CCallHelpers::Label> exceptionHandler { Box<CCallHelpers::Label>::create() };
-    B3::StackSlotValue* capturedValue { nullptr };
+    B3::StackSlot* capturedValue { nullptr };
 #else // FTL_USES_B3
     unsigned handleStackOverflowExceptionStackmapID { UINT_MAX };
     unsigned handleExceptionStackmapID { UINT_MAX };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to