Ignore:
Timestamp:
Aug 15, 2017, 1:13:54 PM (8 years ago)
Author:
[email protected]
Message:

Enable named offsets into JSC bytecodes
https://bugs.webkit.org/show_bug.cgi?id=175561

Reviewed by Mark Lam.

This patch adds the ability to add named offsets into JSC's
bytecodes. In the bytecode json file, instead of listing a
length, you can now list a set of names and their types. Each
opcode with an offsets property will have a struct named after the
opcode by in our C++ naming style. For example,
op_overrides_has_instance would become OpOverridesHasInstance. The
struct has the same memory layout as the instruction list has but
comes with handy named accessors.

As a first cut I converted the various instanceof bytecodes to use
named offsets.

As an example op_overrides_has_instance produces the following struct:

struct OpOverridesHasInstance {
public:

Opcode& opcode() { return *reinterpret_cast<Opcode*>(&m_opcode); }
const Opcode& opcode() const { return *reinterpret_cast<const Opcode*>(&m_opcode); }
int& dst() { return *reinterpret_cast<int*>(&m_dst); }
const int& dst() const { return *reinterpret_cast<const int*>(&m_dst); }
int& constructor() { return *reinterpret_cast<int*>(&m_constructor); }
const int& constructor() const { return *reinterpret_cast<const int*>(&m_constructor); }
int& hasInstanceValue() { return *reinterpret_cast<int*>(&m_hasInstanceValue); }
const int& hasInstanceValue() const { return *reinterpret_cast<const int*>(&m_hasInstanceValue); }

private:

friend class LLIntOffsetsExtractor;
std::aligned_storage<sizeof(Opcode), sizeof(Instruction)>::type m_opcode;
std::aligned_storage<sizeof(int), sizeof(Instruction)>::type m_dst;
std::aligned_storage<sizeof(int), sizeof(Instruction)>::type m_constructor;
std::aligned_storage<sizeof(int), sizeof(Instruction)>::type m_hasInstanceValue;

};

  • CMakeLists.txt:
  • DerivedSources.make:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • bytecode/BytecodeList.json:
  • dfg/DFGByteCodeParser.cpp:

(JSC::DFG::ByteCodeParser::parseBlock):

  • generate-bytecode-files:
  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_overrides_has_instance):
(JSC::JIT::emit_op_instanceof):
(JSC::JIT::emitSlow_op_instanceof):
(JSC::JIT::emitSlow_op_instanceof_custom):

  • jit/JITOpcodes32_64.cpp:

(JSC::JIT::emit_op_overrides_has_instance):
(JSC::JIT::emit_op_instanceof):
(JSC::JIT::emitSlow_op_instanceof):
(JSC::JIT::emitSlow_op_instanceof_custom):

  • llint/LLIntOffsetsExtractor.cpp:
  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/generate-bytecode-files

    r217526 r220753  
    105105    return sha1.hexdigest()
    106106
     107
     108def toCpp(name):
     109    camelCase = re.sub(r'([^a-z0-9].)', lambda c: c.group(0)[1].upper(), name)
     110    CamelCase = camelCase[:1].upper() + camelCase[1:]
     111    return CamelCase
     112
     113
     114def writeInstructionAccessor(bytecodeHFile, typeName, name):
     115    bytecodeHFile.write("    {0}& {1}() {{ return *reinterpret_cast<{0}*>(&m_{1}); }}\n".format(typeName, name))
     116    bytecodeHFile.write("    const {0}& {1}() const {{ return *reinterpret_cast<const {0}*>(&m_{1}); }}\n".format(typeName, name))
     117
     118
     119def writeInstructionMember(bytecodeHFile, typeName, name):
     120    bytecodeHFile.write("    std::aligned_storage<sizeof({0}), sizeof(Instruction)>::type m_{1};\n".format(typeName, name))
     121
     122
     123def writeStruct(bytecodeHFile, bytecode):
     124    bytecodeHFile.write("struct {0} {{\n".format(toCpp(bytecode["name"])))
     125    bytecodeHFile.write("public:\n")
     126
     127    writeInstructionAccessor(bytecodeHFile, "Opcode", "opcode")
     128    for offset in bytecode["offsets"]:
     129        for name, typeName in offset.iteritems():
     130            writeInstructionAccessor(bytecodeHFile, typeName, name)
     131
     132    bytecodeHFile.write("\nprivate:\n")
     133    bytecodeHFile.write("    friend class LLIntOffsetsExtractor;\n\n")
     134
     135    writeInstructionMember(bytecodeHFile, "Opcode", "opcode")
     136    for offset in bytecode["offsets"]:
     137        for name, typeName in offset.iteritems():
     138            writeInstructionMember(bytecodeHFile, typeName, name)
     139    bytecodeHFile.write("};\n\n")
     140
     141
    107142if __name__ == "__main__":
    108143    parser = optparse.OptionParser(usage = "usage: %prog [--bytecodes_h <FILE>] [--init_bytecodes_asm <FILE>] <bytecode-json-file>")
    109144    parser.add_option("-b", "--bytecodes_h", dest = "bytecodesHFileName", help = "generate bytecodes macro .h FILE", metavar = "FILE")
     145    parser.add_option("-s", "--bytecode_structs_h", dest = "bytecodeStructsHFileName", help = "generate bytecodes macro .h FILE", metavar = "FILE")
    110146    parser.add_option("-a", "--init_bytecodes_asm", dest = "initASMFileName", help="generate ASM bytecodes init FILE", metavar = "FILE")
    111147    (options, args) = parser.parse_args()
     
    122158
    123159    bytecodeHFilename = options.bytecodesHFileName
     160    bytecodeStructsHFilename = options.bytecodeStructsHFileName
    124161    initASMFileName = options.initASMFileName
    125162
    126     if not bytecodeHFilename and not initASMFileName:
     163    if not bytecodeHFilename and not initASMFileName and not bytecodeStructsHFilename:
    127164        parser.print_help()
    128165        exit(0)
     
    133170        try:
    134171            bytecodeHReadFile = open(bytecodeHFilename, "rb")
    135            
     172
    136173            hashLine = bytecodeHReadFile.readline()
    137174            if hashLine != hFileHashString:
     
    141178        else:
    142179            bytecodeHReadFile.close()
     180
     181    if bytecodeStructsHFilename:
     182        try:
     183            bytecodeStructsHReadFile = open(bytecodeStructsHFilename, "rb")
     184
     185            hashLine = bytecodeStructsHReadFile.readline()
     186            if hashLine != hFileHashString:
     187                needToGenerate = True
     188        except:
     189            needToGenerate = True
     190        else:
     191            bytecodeStructsHReadFile.close()
    143192
    144193    if initASMFileName:
     
    160209        bytecodeHFile = openOrExit(bytecodeHFilename, "wb")
    161210
     211    if bytecodeStructsHFilename:
     212        bytecodeStructsHFile = openOrExit(bytecodeStructsHFilename, "wb")
     213
    162214    if initASMFileName:
    163215        initBytecodesFile = openOrExit(initASMFileName, "wb")
     
    172224        bytecodeHFile.write(cCopyrightMsg % bytecodeJSONFile)
    173225        bytecodeHFile.write("#pragma once\n\n")
     226
     227    if bytecodeStructsHFilename:
     228        bytecodeStructsHFile.write(hFileHashString)
     229        bytecodeStructsHFile.write(cCopyrightMsg % bytecodeJSONFile)
     230        bytecodeStructsHFile.write("#pragma once\n\n")
     231        bytecodeStructsHFile.write("#include \"Instruction.h\"\n")
     232        bytecodeStructsHFile.write("\n")
    174233
    175234    if initASMFileName:
     
    194253                if "length" in bytecode:
    195254                    length = bytecode["length"]
     255                elif "offsets" in bytecode:
     256                    # Add one for the opcode
     257                    length = len(bytecode["offsets"]) + 1
    196258
    197259                bytecodeHFile.write("    macro({0}, {1})".format(bytecode["name"], length))
     
    201263            bytecodeHFile.write("\n\n")
    202264            bytecodeHFile.write("#define NUMBER_OF_{0}_IDS {1}\n\n".format(section["macroNameComponent"], bytecodeNum))
     265
     266
     267        if bytecodeStructsHFilename and section['emitInStructsFile']:
     268            bytecodeStructsHFile.write("namespace JSC {\n\n")
     269
     270            for bytecode in section["bytecodes"]:
     271                if not "offsets" in bytecode:
     272                    continue
     273                writeStruct(bytecodeStructsHFile, bytecode)
     274
     275            bytecodeStructsHFile.write("} // namespace JSC \n")
    203276
    204277        if bytecodeHFilename and section['emitOpcodeIDStringValuesInHFile']:
Note: See TracChangeset for help on using the changeset viewer.