Changeset 207360 in webkit


Ignore:
Timestamp:
Oct 14, 2016 4:22:07 PM (8 years ago)
Author:
keith_miller@apple.com
Message:

B3 needs a special WasmAddress Opcode
https://bugs.webkit.org/show_bug.cgi?id=163394

Reviewed by Filip Pizlo.

Source/JavaScriptCore:

This patch adds support for WasmAddress. WasmAddress will be used by
Wasm to compute the address of a memory operation from the pinned
base pointer. WasmAddress takes an IntPtr so we can avoid emitting
unnecessary Move32s in Air. This could happen in the following case:

@ptr = Trunc(...)
WasmAddress(@ptr, pinnedGPR)
...
PatchPoint(...) Do Wasm call
WasmAddress(@ptr, pinnedGPR)
...

In this case we will not be able to CSE the WasmAddresses since the
call writes to pinnedGPR. Thus if WasmAddress took an Int32 we would need
to emit an extra Move32 at the second WasmAddress to ensure it saw a proper
32-bit value. If Wasm ensures that there there is a leading ZExt32 then
the duplicated moves become unnecessary.

  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • b3/B3LowerToAir.cpp:

(JSC::B3::Air::LowerToAir::effectiveAddr):
(JSC::B3::Air::LowerToAir::lower):

  • b3/B3Opcode.cpp:

(WTF::printInternal):

  • b3/B3Opcode.h:
  • b3/B3Validate.cpp:
  • b3/B3Value.cpp:

(JSC::B3::Value::effects):

  • b3/B3WasmAddressValue.cpp: Added.

(JSC::B3::WasmAddressValue::~WasmAddressValue):
(JSC::B3::WasmAddressValue::dumpMeta):
(JSC::B3::WasmAddressValue::cloneImpl):
(JSC::B3::WasmAddressValue::WasmAddressValue):

  • b3/B3WasmAddressValue.h: Added.
  • b3/testb3.cpp:

(JSC::B3::testWasmAddress):
(JSC::B3::run):

Websites/webkit.org:

Update the b3 docs for the new WasmAddress opcode.

  • docs/b3/intermediate-representation.html:
Location:
trunk
Files:
2 added
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r207266 r207360  
    173173    b3/B3Variable.cpp
    174174    b3/B3VariableValue.cpp
     175    b3/B3WasmAddressValue.cpp
    175176    b3/B3WasmBoundsCheckValue.cpp
    176177
  • trunk/Source/JavaScriptCore/ChangeLog

    r207347 r207360  
     12016-10-14  Keith Miller  <keith_miller@apple.com>
     2
     3        B3 needs a special WasmAddress Opcode
     4        https://bugs.webkit.org/show_bug.cgi?id=163394
     5
     6        Reviewed by Filip Pizlo.
     7
     8        This patch adds support for WasmAddress. WasmAddress will be used by
     9        Wasm to compute the address of a memory operation from the pinned
     10        base pointer. WasmAddress takes an IntPtr so we can avoid emitting
     11        unnecessary Move32s in Air. This could happen in the following case:
     12
     13        @ptr = Trunc(...)
     14        WasmAddress(@ptr, pinnedGPR)
     15        ...
     16        PatchPoint(...) // Do Wasm call
     17        WasmAddress(@ptr, pinnedGPR)
     18        ...
     19
     20        In this case we will not be able to CSE the WasmAddresses since the
     21        call writes to pinnedGPR. Thus if WasmAddress took an Int32 we would need
     22        to emit an extra Move32 at the second WasmAddress to ensure it saw a proper
     23        32-bit value. If Wasm ensures that there there is a leading ZExt32 then
     24        the duplicated moves become unnecessary.
     25
     26        * CMakeLists.txt:
     27        * JavaScriptCore.xcodeproj/project.pbxproj:
     28        * b3/B3LowerToAir.cpp:
     29        (JSC::B3::Air::LowerToAir::effectiveAddr):
     30        (JSC::B3::Air::LowerToAir::lower):
     31        * b3/B3Opcode.cpp:
     32        (WTF::printInternal):
     33        * b3/B3Opcode.h:
     34        * b3/B3Validate.cpp:
     35        * b3/B3Value.cpp:
     36        (JSC::B3::Value::effects):
     37        * b3/B3WasmAddressValue.cpp: Added.
     38        (JSC::B3::WasmAddressValue::~WasmAddressValue):
     39        (JSC::B3::WasmAddressValue::dumpMeta):
     40        (JSC::B3::WasmAddressValue::cloneImpl):
     41        (JSC::B3::WasmAddressValue::WasmAddressValue):
     42        * b3/B3WasmAddressValue.h: Added.
     43        * b3/testb3.cpp:
     44        (JSC::B3::testWasmAddress):
     45        (JSC::B3::run):
     46
    1472016-10-14  Joseph Pecoraro  <pecoraro@apple.com>
    248
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r207266 r207360  
    12221222                539EB0811D55608A00C82EF7 /* testWASM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 539EB0711D553DF800C82EF7 /* testWASM.cpp */; };
    12231223                539FB8BA1C99DA7C00940FA1 /* JSArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */; };
     1224                53D444DC1DAF08AB00B92784 /* B3WasmAddressValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 53D444DB1DAF08AB00B92784 /* B3WasmAddressValue.h */; };
     1225                53D444DE1DAF09A000B92784 /* B3WasmAddressValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53D444DD1DAF09A000B92784 /* B3WasmAddressValue.cpp */; };
    12241226                53F40E851D58F9770099A1B6 /* WASMSections.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E841D58F9770099A1B6 /* WASMSections.h */; };
    12251227                53F40E8B1D5901BB0099A1B6 /* WASMFunctionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E8A1D5901BB0099A1B6 /* WASMFunctionParser.h */; };
     
    34623464                539EB0801D55607000C82EF7 /* testWASM */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testWASM; sourceTree = BUILT_PRODUCTS_DIR; };
    34633465                539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSArrayInlines.h; sourceTree = "<group>"; };
     3466                53D444DB1DAF08AB00B92784 /* B3WasmAddressValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3WasmAddressValue.h; path = b3/B3WasmAddressValue.h; sourceTree = "<group>"; };
     3467                53D444DD1DAF09A000B92784 /* B3WasmAddressValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3WasmAddressValue.cpp; path = b3/B3WasmAddressValue.cpp; sourceTree = "<group>"; };
    34643468                53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArrayViewPrototype.cpp; sourceTree = "<group>"; };
    34653469                53F40E841D58F9770099A1B6 /* WASMSections.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMSections.h; sourceTree = "<group>"; };
     
    50065010                                0F2BBD941C5FF3F50023EF23 /* B3VariableValue.cpp */,
    50075011                                0F2BBD951C5FF3F50023EF23 /* B3VariableValue.h */,
     5012                                53D444DD1DAF09A000B92784 /* B3WasmAddressValue.cpp */,
     5013                                53D444DB1DAF08AB00B92784 /* B3WasmAddressValue.h */,
    50085014                                0FEC85AE1BDB5D5E0080FF74 /* testb3.cpp */,
    50095015                        );
     
    72497255                                0F4570391BE44C910062A629 /* AirEliminateDeadCode.h in Headers */,
    72507256                                79B00CBD1C6AB07E0088C65D /* ProxyConstructor.h in Headers */,
     7257                                53D444DC1DAF08AB00B92784 /* B3WasmAddressValue.h in Headers */,
    72517258                                990DA67F1C8E316A00295159 /* generate_objc_protocol_type_conversions_implementation.py in Headers */,
    72527259                                DC17E8191C9C91DB008A6AB3 /* ShadowChickenInlines.h in Headers */,
     
    97879794                                1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */,
    97889795                                14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
     9796                                53D444DE1DAF09A000B92784 /* B3WasmAddressValue.cpp in Sources */,
    97899797                                14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
    97909798                                A7CA3AE317DA41AE006538AF /* WeakMapConstructor.cpp in Sources */,
  • trunk/Source/JavaScriptCore/b3/B3LowerToAir.cpp

    r207266 r207360  
    5555#include "B3Variable.h"
    5656#include "B3VariableValue.h"
     57#include "B3WasmAddressValue.h"
    5758#include <wtf/IndexMap.h>
    5859#include <wtf/IndexSet.h>
     
    509510            return Arg::stack(m_stackToStack.get(address->as<SlotBaseValue>()->slot()), offset);
    510511
     512        case WasmAddress: {
     513            WasmAddressValue* wasmAddress = address->as<WasmAddressValue>();
     514            Value* pointer = wasmAddress->child(0);
     515            ASSERT(Arg::isValidIndexForm(1, offset, width));
     516            if (m_locked.contains(pointer))
     517                return fallback();
     518
     519            // FIXME: We should support ARM64 LDR 32-bit addressing, which will
     520            // allow us to fuse a Shl ptr, 2 into the address. Additionally, and
     521            // perhaps more importantly, it would allow us to avoid a truncating
     522            // move. See: https://bugs.webkit.org/show_bug.cgi?id=163465
     523
     524            return Arg::index(Tmp(wasmAddress->pinnedGPR()), tmp(pointer), 1, offset);
     525        }
     526
    511527        default:
    512528            return fallback();
     
    22772293            return;
    22782294        }
    2279            
     2295
     2296        case WasmAddress: {
     2297            WasmAddressValue* address = m_value->as<WasmAddressValue>();
     2298
     2299            append(Add64, Arg(address->pinnedGPR()), tmp(address));
     2300            return;
     2301        }
     2302
    22802303        case Fence: {
    22812304            FenceValue* fence = m_value->as<FenceValue>();
  • trunk/Source/JavaScriptCore/b3/B3Opcode.cpp

    r207266 r207360  
    252252        out.print("Store");
    253253        return;
     254    case WasmAddress:
     255        out.print("WasmAddress");
     256        return;
    254257    case Fence:
    255258        out.print("Fence");
  • trunk/Source/JavaScriptCore/b3/B3Opcode.h

    r207266 r207360  
    158158    // This is a polymorphic store for Int32, Int64, Float, and Double.
    159159    Store,
     160
     161    // This is used to compute the actual address of a Wasm memory operation. It takes an IntPtr
     162    // and a pinned register then computes the appropriate IntPtr address. For the use-case of
     163    // Wasm it is important that the first child initially be a ZExt32 so the top bits are cleared.
     164    // We do WasmAddress(ZExt32(ptr), ...) so that we can avoid generating extraneous moves in Air.
     165    WasmAddress,
    160166   
    161167    // This is used to represent standalone fences - i.e. fences that are not part of other
  • trunk/Source/JavaScriptCore/b3/B3Validate.cpp

    r207266 r207360  
    371371                VALIDATE(value->type() == Void, ("At ", *value));
    372372                validateStackAccess(value);
     373                break;
     374            case WasmAddress:
     375                VALIDATE(!value->kind().hasExtraBits(), ("At ", *value));
     376                VALIDATE(value->numChildren() == 1, ("At ", *value));
     377                VALIDATE(value->child(0)->type() == pointerType(), ("At ", *value));
     378                VALIDATE(value->type() == pointerType(), ("At ", *value));
    373379                break;
    374380            case CCall:
  • trunk/Source/JavaScriptCore/b3/B3Value.cpp

    r207266 r207360  
    586586        result.writes = as<MemoryValue>()->range();
    587587        result.controlDependent = true;
     588        break;
     589    case WasmAddress:
     590        result.readsPinned = true;
    588591        break;
    589592    case Fence: {
  • trunk/Source/JavaScriptCore/b3/testb3.cpp

    r207266 r207360  
    5555#include "B3ValueInlines.h"
    5656#include "B3VariableValue.h"
     57#include "B3WasmAddressValue.h"
    5758#include "B3WasmBoundsCheckValue.h"
    5859#include "CCallHelpers.h"
     
    1376013761    CHECK_EQ(invoke<int32_t>(*code, 3, 2 + offset), 42);
    1376113762    CHECK_EQ(invoke<int32_t>(*code, 2, 2 + offset), 42);
     13763}
     13764
     13765void testWasmAddress()
     13766{
     13767    Procedure proc;
     13768    GPRReg pinnedGPR = GPRInfo::argumentGPR2;
     13769    proc.pinRegister(pinnedGPR);
     13770
     13771    unsigned loopCount = 100;
     13772    Vector<unsigned> values(loopCount);
     13773    unsigned numToStore = 42;
     13774
     13775    BasicBlock* root = proc.addBlock();
     13776    BasicBlock* header = proc.addBlock();
     13777    BasicBlock* body = proc.addBlock();
     13778    BasicBlock* continuation = proc.addBlock();
     13779
     13780    // Root
     13781    Value* loopCountValue = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
     13782    Value* valueToStore = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
     13783    UpsilonValue* beginUpsilon = root->appendNew<UpsilonValue>(proc, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
     13784    root->appendNewControlValue(proc, Jump, Origin(), header);
     13785
     13786    // Header
     13787    Value* indexPhi = header->appendNew<Value>(proc, Phi, Int32, Origin());
     13788    header->appendNewControlValue(proc, Branch, Origin(),
     13789        header->appendNew<Value>(proc, Below, Origin(), indexPhi, loopCountValue),
     13790        body, continuation);
     13791
     13792    // Body
     13793    Value* pointer = body->appendNew<Value>(proc, Mul, Origin(), indexPhi,
     13794        body->appendNew<Const32Value>(proc, Origin(), sizeof(unsigned)));
     13795    pointer = body->appendNew<Value>(proc, ZExt32, Origin(), pointer);
     13796    body->appendNew<MemoryValue>(proc, Store, Origin(), valueToStore,
     13797        body->appendNew<WasmAddressValue>(proc, Origin(), pointer, pinnedGPR));
     13798    UpsilonValue* incUpsilon = body->appendNew<UpsilonValue>(proc, Origin(),
     13799        body->appendNew<Value>(proc, Add, Origin(), indexPhi,
     13800            body->appendNew<Const32Value>(proc, Origin(), 1)));
     13801    body->appendNewControlValue(proc, Jump, Origin(), header);
     13802
     13803    // Continuation
     13804    continuation->appendNewControlValue(proc, Return, Origin());
     13805
     13806    beginUpsilon->setPhi(indexPhi);
     13807    incUpsilon->setPhi(indexPhi);
     13808
     13809
     13810    auto code = compile(proc);
     13811    invoke<void>(*code, loopCount, numToStore, values.data());
     13812    for (unsigned value : values)
     13813        CHECK_EQ(numToStore, value);
    1376213814}
    1376313815
     
    1520615258    RUN(testWasmBoundsCheck(10000));
    1520715259    RUN(testWasmBoundsCheck(std::numeric_limits<unsigned>::max() - 5));
     15260    RUN(testWasmAddress());
    1520815261
    1520915262    if (isX86()) {
  • trunk/Websites/webkit.org/ChangeLog

    r207350 r207360  
     12016-10-14  Keith Miller  <keith_miller@apple.com>
     2
     3        B3 needs a special WasmAddress Opcode
     4        https://bugs.webkit.org/show_bug.cgi?id=163394
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Update the b3 docs for the new WasmAddress opcode.
     9
     10        * docs/b3/intermediate-representation.html:
     11
    1122016-10-14  Simon Fraser  <simon.fraser@apple.com>
    213
  • trunk/Websites/webkit.org/docs/b3/intermediate-representation.html

    r207266 r207360  
    424424        compile-time 32-bit signed integer offset to the second child.  Misaligned stores are
    425425        not penalized.  Must use the MemoryValue class.  May have the Traps flag set.</dd>
    426      
     426
     427      <dt>IntPtr WasmAddress(IntPtr, pinnedGPR)</dt>
     428      <dd>This is used to compute the address of a wasm memory load from a pinned base GPR.
     429        Must use the WasmAddressValue class.</dd>
     430
     431
    427432      <dt>Void Fence()</dt>
    428433      <dd>Abstracts standalone data fences on x86 and ARM. Must use the FenceValue class, which has
Note: See TracChangeset for help on using the changeset viewer.