Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (194968 => 194969)
--- trunk/Source/_javascript_Core/ChangeLog 2016-01-13 19:22:28 UTC (rev 194968)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-01-13 19:33:02 UTC (rev 194969)
@@ -1,3 +1,38 @@
+2016-01-13 Benjamin Poulain <bpoul...@apple.com>
+
+ [JSC] Legalize Memory Offsets for ARM64 before lowering to Air
+ https://bugs.webkit.org/show_bug.cgi?id=153065
+
+ Reviewed by Mark Lam.
+ Reviewed by Filip Pizlo.
+
+ On ARM64, we cannot use signed 32bits offset for memory addressing.
+ There are two available addressing: signed 9bits and unsigned scaled 12bits.
+ Air already knows about it.
+
+ In this patch, the offsets are changed to something valid for ARM64
+ prior to lowering. When an offset is invalid, it is just computed
+ before the instruction and used as the base for addressing.
+
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * b3/B3Generate.cpp:
+ (JSC::B3::generateToAir):
+ * b3/B3LegalizeMemoryOffsets.cpp: Added.
+ (JSC::B3::legalizeMemoryOffsets):
+ * b3/B3LegalizeMemoryOffsets.h: Added.
+ * b3/B3LowerToAir.cpp:
+ (JSC::B3::Air::LowerToAir::effectiveAddr): Deleted.
+ * b3/testb3.cpp:
+ (JSC::B3::testLoadWithOffsetImpl):
+ (JSC::B3::testLoadOffsetImm9Max):
+ (JSC::B3::testLoadOffsetImm9MaxPlusOne):
+ (JSC::B3::testLoadOffsetImm9MaxPlusTwo):
+ (JSC::B3::testLoadOffsetImm9Min):
+ (JSC::B3::testLoadOffsetImm9MinMinusOne):
+ (JSC::B3::testLoadOffsetScaledUnsignedImm12Max):
+ (JSC::B3::testLoadOffsetScaledUnsignedOverImm12Max):
+ (JSC::B3::run):
+
2016-01-12 Per Arne Vollan <pe...@outlook.com>
[FTL][Win64] Compile error.
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (194968 => 194969)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-01-13 19:22:28 UTC (rev 194968)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-01-13 19:33:02 UTC (rev 194969)
@@ -1152,6 +1152,8 @@
43422A631C158E6D00E2EB98 /* B3ConstFloatValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 43422A611C15871B00E2EB98 /* B3ConstFloatValue.h */; };
43422A661C16267500E2EB98 /* B3ReduceDoubleToFloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43422A641C16221E00E2EB98 /* B3ReduceDoubleToFloat.cpp */; };
43422A671C16267800E2EB98 /* B3ReduceDoubleToFloat.h in Headers */ = {isa = PBXBuildFile; fileRef = 43422A651C16221E00E2EB98 /* B3ReduceDoubleToFloat.h */; };
+ 436E54531C468E7400B5AF73 /* B3LegalizeMemoryOffsets.h in Headers */ = {isa = PBXBuildFile; fileRef = 436E54521C468E5F00B5AF73 /* B3LegalizeMemoryOffsets.h */; };
+ 436E54541C468E7700B5AF73 /* B3LegalizeMemoryOffsets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 436E54511C468E5F00B5AF73 /* B3LegalizeMemoryOffsets.cpp */; };
43AB26C61C1A535900D82AE6 /* B3MathExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 43AB26C51C1A52F700D82AE6 /* B3MathExtras.h */; };
43AB26C71C1A535C00D82AE6 /* B3MathExtras.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43AB26C41C1A52F700D82AE6 /* B3MathExtras.cpp */; };
43C392AB1C3BEB0500241F53 /* AssemblerCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 43C392AA1C3BEB0000241F53 /* AssemblerCommon.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -3260,6 +3262,8 @@
43422A611C15871B00E2EB98 /* B3ConstFloatValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ConstFloatValue.h; path = b3/B3ConstFloatValue.h; sourceTree = "<group>"; };
43422A641C16221E00E2EB98 /* B3ReduceDoubleToFloat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3ReduceDoubleToFloat.cpp; path = b3/B3ReduceDoubleToFloat.cpp; sourceTree = "<group>"; };
43422A651C16221E00E2EB98 /* B3ReduceDoubleToFloat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3ReduceDoubleToFloat.h; path = b3/B3ReduceDoubleToFloat.h; sourceTree = "<group>"; };
+ 436E54511C468E5F00B5AF73 /* B3LegalizeMemoryOffsets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3LegalizeMemoryOffsets.cpp; path = b3/B3LegalizeMemoryOffsets.cpp; sourceTree = "<group>"; };
+ 436E54521C468E5F00B5AF73 /* B3LegalizeMemoryOffsets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3LegalizeMemoryOffsets.h; path = b3/B3LegalizeMemoryOffsets.h; sourceTree = "<group>"; };
43AB26C41C1A52F700D82AE6 /* B3MathExtras.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3MathExtras.cpp; path = b3/B3MathExtras.cpp; sourceTree = "<group>"; };
43AB26C51C1A52F700D82AE6 /* B3MathExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3MathExtras.h; path = b3/B3MathExtras.h; sourceTree = "<group>"; };
43C392AA1C3BEB0000241F53 /* AssemblerCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssemblerCommon.h; sourceTree = "<group>"; };
@@ -3372,8 +3376,8 @@
7013CA8A1B491A9400CAE613 /* JSJob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSJob.h; sourceTree = "<group>"; };
7035587C1C418419004BD7BF /* MapPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = MapPrototype.js; sourceTree = "<group>"; };
7035587D1C418419004BD7BF /* SetPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = SetPrototype.js; sourceTree = "<group>"; };
- 7035587E1C418458004BD7BF /* MapPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MapPrototype.lut.h; path = MapPrototype.lut.h; sourceTree = "<group>"; };
- 7035587F1C418458004BD7BF /* SetPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SetPrototype.lut.h; path = SetPrototype.lut.h; sourceTree = "<group>"; };
+ 7035587E1C418458004BD7BF /* MapPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapPrototype.lut.h; sourceTree = "<group>"; };
+ 7035587F1C418458004BD7BF /* SetPrototype.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SetPrototype.lut.h; sourceTree = "<group>"; };
704FD35305697E6D003DBED9 /* BooleanObject.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = BooleanObject.h; sourceTree = "<group>"; tabWidth = 8; };
705B41A31A6E501E00716757 /* Symbol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Symbol.cpp; sourceTree = "<group>"; };
705B41A41A6E501E00716757 /* Symbol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Symbol.h; sourceTree = "<group>"; };
@@ -4710,6 +4714,8 @@
0FEC85B41BE1462F0080FF74 /* B3InsertionSet.cpp */,
0FEC85B51BE1462F0080FF74 /* B3InsertionSet.h */,
0FEC85B61BE1462F0080FF74 /* B3InsertionSetInlines.h */,
+ 436E54511C468E5F00B5AF73 /* B3LegalizeMemoryOffsets.cpp */,
+ 436E54521C468E5F00B5AF73 /* B3LegalizeMemoryOffsets.h */,
0F338E191BF286EA0013C88F /* B3LowerMacros.cpp */,
0F338E1A1BF286EA0013C88F /* B3LowerMacros.h */,
4319DA011C1BE3C1001D260B /* B3LowerMacrosAfterOptimizations.cpp */,
@@ -7937,6 +7943,7 @@
BCDE3AB80E6C82F5001453A7 /* Structure.h in Headers */,
7E4EE7090EBB7963005934AA /* StructureChain.h in Headers */,
2AAAA31218BD49D100394CC8 /* StructureIDBlob.h in Headers */,
+ 436E54531C468E7400B5AF73 /* B3LegalizeMemoryOffsets.h in Headers */,
2AF7382D18BBBF92008A5A37 /* StructureIDTable.h in Headers */,
0FD2C92416D01EE900C7803F /* StructureInlines.h in Headers */,
C2FE18A416BAEC4000AF3061 /* StructureRareData.h in Headers */,
@@ -8614,6 +8621,7 @@
0FEC85091BDACDAC0080FF74 /* B3Common.cpp in Sources */,
0FEC850B1BDACDAC0080FF74 /* B3Commutativity.cpp in Sources */,
0FEC850D1BDACDAC0080FF74 /* B3Const32Value.cpp in Sources */,
+ 436E54541C468E7700B5AF73 /* B3LegalizeMemoryOffsets.cpp in Sources */,
0FEC850F1BDACDAC0080FF74 /* B3Const64Value.cpp in Sources */,
0FEC85111BDACDAC0080FF74 /* B3ConstDoubleValue.cpp in Sources */,
0FEC85131BDACDAC0080FF74 /* B3ControlValue.cpp in Sources */,
Modified: trunk/Source/_javascript_Core/b3/B3Generate.cpp (194968 => 194969)
--- trunk/Source/_javascript_Core/b3/B3Generate.cpp 2016-01-13 19:22:28 UTC (rev 194968)
+++ trunk/Source/_javascript_Core/b3/B3Generate.cpp 2016-01-13 19:33:02 UTC (rev 194969)
@@ -32,6 +32,7 @@
#include "AirGenerate.h"
#include "AirInstInlines.h"
#include "B3Common.h"
+#include "B3LegalizeMemoryOffsets.h"
#include "B3LowerMacros.h"
#include "B3LowerMacrosAfterOptimizations.h"
#include "B3LowerToAir.h"
@@ -85,6 +86,8 @@
lowerMacrosAfterOptimizations(procedure);
+ legalizeMemoryOffsets(procedure);
+
moveConstants(procedure);
if (shouldValidateIR())
Added: trunk/Source/_javascript_Core/b3/B3LegalizeMemoryOffsets.cpp (0 => 194969)
--- trunk/Source/_javascript_Core/b3/B3LegalizeMemoryOffsets.cpp (rev 0)
+++ trunk/Source/_javascript_Core/b3/B3LegalizeMemoryOffsets.cpp 2016-01-13 19:33:02 UTC (rev 194969)
@@ -0,0 +1,92 @@
+/*
+ * 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 "B3LegalizeMemoryOffsets.h"
+
+#if ENABLE(B3_JIT)
+
+#include "AirArg.h"
+#include "B3InsertionSetInlines.h"
+#include "B3MemoryValue.h"
+#include "B3PhaseScope.h"
+#include "B3ProcedureInlines.h"
+
+namespace JSC { namespace B3 {
+
+namespace {
+
+class LegalizeMemoryOffsets {
+public:
+ LegalizeMemoryOffsets(Procedure& proc)
+ : m_proc(proc)
+ , m_insertionSet(proc)
+ {
+ }
+
+ void run()
+ {
+ if (!isARM64())
+ return;
+
+ for (BasicBlock* block : m_proc) {
+ for (unsigned index = 0; index < block->size(); ++index) {
+ MemoryValue* memoryValue = block->at(index)->as<MemoryValue>();
+ if (!memoryValue)
+ continue;
+
+ int32_t offset = memoryValue->offset();
+ Air::Arg::Width width = Air::Arg::widthForBytes(memoryValue->accessByteSize());
+ if (!Air::Arg::isValidAddrForm(offset, width)) {
+ Value* base = memoryValue->lastChild();
+ Value* offsetValue = m_insertionSet.insertIntConstant(index, memoryValue->origin(), pointerType(), offset);
+ Value* resolvedAddress = m_proc.add<Value>(Add, memoryValue->origin(), base, offsetValue);
+ m_insertionSet.insertValue(index, resolvedAddress);
+
+ memoryValue->lastChild() = resolvedAddress;
+ memoryValue->setOffset(0);
+ }
+ }
+ m_insertionSet.execute(block);
+ }
+ }
+
+ Procedure& m_proc;
+ InsertionSet m_insertionSet;
+};
+
+} // anonymous namespace
+
+void legalizeMemoryOffsets(Procedure& proc)
+{
+ PhaseScope phaseScope(proc, "legalizeMemoryOffsets");
+ LegalizeMemoryOffsets legalizeMemoryOffsets(proc);
+ legalizeMemoryOffsets.run();
+}
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
Added: trunk/Source/_javascript_Core/b3/B3LegalizeMemoryOffsets.h (0 => 194969)
--- trunk/Source/_javascript_Core/b3/B3LegalizeMemoryOffsets.h (rev 0)
+++ trunk/Source/_javascript_Core/b3/B3LegalizeMemoryOffsets.h 2016-01-13 19:33:02 UTC (rev 194969)
@@ -0,0 +1,44 @@
+/*
+ * 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 B3LegalizeMemoryOffsets_h
+#define B3LegalizeMemoryOffsets_h
+
+#if ENABLE(B3_JIT)
+
+namespace JSC { namespace B3 {
+
+class Procedure;
+
+// If the offsets of a MemoryValue cannot be represented in the target instruction set,
+// compute it explicitly.
+void legalizeMemoryOffsets(Procedure&);
+
+} } // namespace JSC::B3
+
+#endif // ENABLE(B3_JIT)
+
+#endif // B3LegalizeMemoryOffsets_h
+
Modified: trunk/Source/_javascript_Core/b3/B3LowerToAir.cpp (194968 => 194969)
--- trunk/Source/_javascript_Core/b3/B3LowerToAir.cpp 2016-01-13 19:22:28 UTC (rev 194968)
+++ trunk/Source/_javascript_Core/b3/B3LowerToAir.cpp 2016-01-13 19:33:02 UTC (rev 194969)
@@ -357,10 +357,6 @@
// This turns the given operand into an address.
Arg effectiveAddr(Value* address, int32_t offset, Arg::Width width)
{
- // B3 allows any memory operation to have a 32-bit offset. That's not how some architectures
- // work. We solve this by requiring a just-before-lowering phase that legalizes offsets.
- // FIXME: Implement such a legalization phase.
- // https://bugs.webkit.org/show_bug.cgi?id=152530
ASSERT(Arg::isValidAddrForm(offset, width));
auto fallback = [&] () -> Arg {
Modified: trunk/Source/_javascript_Core/b3/testb3.cpp (194968 => 194969)
--- trunk/Source/_javascript_Core/b3/testb3.cpp 2016-01-13 19:22:28 UTC (rev 194968)
+++ trunk/Source/_javascript_Core/b3/testb3.cpp 2016-01-13 19:33:02 UTC (rev 194969)
@@ -136,6 +136,77 @@
CHECK(compileAndRun<int>(proc) == 42);
}
+void testLoadWithOffsetImpl(int32_t offset64, int32_t offset32)
+{
+ {
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ int64_t x = -42;
+ Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+ root->appendNew<ControlValue>(
+ proc, Return, Origin(),
+ root->appendNew<MemoryValue>(
+ proc, Load, Int64, Origin(),
+ base,
+ offset64));
+
+ char* address = reinterpret_cast<char*>(&x) - offset64;
+ CHECK(compileAndRun<int64_t>(proc, address) == -42);
+ }
+ {
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ int32_t x = -42;
+ Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+ root->appendNew<ControlValue>(
+ proc, Return, Origin(),
+ root->appendNew<MemoryValue>(
+ proc, Load, Int32, Origin(),
+ base,
+ offset32));
+
+ char* address = reinterpret_cast<char*>(&x) - offset32;
+ CHECK(compileAndRun<int32_t>(proc, address) == -42);
+ }
+}
+
+void testLoadOffsetImm9Max()
+{
+ testLoadWithOffsetImpl(255, 255);
+}
+
+void testLoadOffsetImm9MaxPlusOne()
+{
+ testLoadWithOffsetImpl(256, 256);
+}
+
+void testLoadOffsetImm9MaxPlusTwo()
+{
+ testLoadWithOffsetImpl(257, 257);
+}
+
+void testLoadOffsetImm9Min()
+{
+ testLoadWithOffsetImpl(-256, -256);
+}
+
+void testLoadOffsetImm9MinMinusOne()
+{
+ testLoadWithOffsetImpl(-257, -257);
+}
+
+void testLoadOffsetScaledUnsignedImm12Max()
+{
+ testLoadWithOffsetImpl(32760, 16380);
+}
+
+void testLoadOffsetScaledUnsignedOverImm12Max()
+{
+ testLoadWithOffsetImpl(32760, 32760);
+ testLoadWithOffsetImpl(32761, 16381);
+ testLoadWithOffsetImpl(32768, 16384);
+}
+
void testArg(int argument)
{
Procedure proc;
@@ -9288,6 +9359,13 @@
RUN(test42());
RUN(testLoad42());
+ RUN(testLoadOffsetImm9Max());
+ RUN(testLoadOffsetImm9MaxPlusOne());
+ RUN(testLoadOffsetImm9MaxPlusTwo());
+ RUN(testLoadOffsetImm9Min());
+ RUN(testLoadOffsetImm9MinMinusOne());
+ RUN(testLoadOffsetScaledUnsignedImm12Max());
+ RUN(testLoadOffsetScaledUnsignedOverImm12Max());
RUN(testArg(43));
RUN(testReturnConst64(5));
RUN(testReturnConst64(-42));