/ bytecode / BytecodeDumper.h
BytecodeDumper.h
  1  /*
  2   * Copyright (C) 2017 Yusuke Suzuki <utatane.tea@gmail.com>
  3   * Copyright (C) 2018-2019 Apple Inc. All rights reserved.
  4   *
  5   * Redistribution and use in source and binary forms, with or without
  6   * modification, are permitted provided that the following conditions
  7   * are met:
  8   * 1. Redistributions of source code must retain the above copyright
  9   *    notice, this list of conditions and the following disclaimer.
 10   * 2. Redistributions in binary form must reproduce the above copyright
 11   *    notice, this list of conditions and the following disclaimer in the
 12   *    documentation and/or other materials provided with the distribution.
 13   *
 14   * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 15   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 16   * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 17   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 18   * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 19   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 20   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 21   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 22   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 23   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 24   * THE POSSIBILITY OF SUCH DAMAGE.
 25   */
 26  
 27  #pragma once
 28  
 29  #include "BytecodeGeneratorBase.h"
 30  #include "CallLinkInfo.h"
 31  #include "ICStatusMap.h"
 32  #include "InstructionStream.h"
 33  #include "StructureStubInfo.h"
 34  
 35  namespace JSC {
 36  
 37  class BytecodeGraph;
 38  
 39  struct Instruction;
 40  
 41  class BytecodeDumperBase {
 42  public:
 43      virtual ~BytecodeDumperBase()
 44      {
 45      }
 46  
 47      void printLocationAndOp(InstructionStream::Offset location, const char* op);
 48  
 49      template<typename T>
 50      void dumpOperand(const char* operandName, T operand, bool isFirst = false)
 51      {
 52          if (!isFirst)
 53              m_out.print(", ");
 54          m_out.print(operandName);
 55          m_out.print(":");
 56          dumpValue(operand);
 57      }
 58  
 59      void dumpValue(VirtualRegister);
 60  
 61      template<typename Traits>
 62      void dumpValue(GenericBoundLabel<Traits>);
 63  
 64      template<typename T>
 65      void dumpValue(T v) { m_out.print(v); }
 66  
 67  protected:
 68      virtual CString registerName(VirtualRegister) const = 0;
 69      virtual int outOfLineJumpOffset(InstructionStream::Offset) const = 0;
 70  
 71      BytecodeDumperBase(PrintStream& out)
 72          : m_out(out)
 73      {
 74      }
 75  
 76      PrintStream& m_out;
 77      InstructionStream::Offset m_currentLocation { 0 };
 78  };
 79  
 80  template<class Block>
 81  class BytecodeDumper : public BytecodeDumperBase {
 82  public:
 83      static void dumpBytecode(Block*, PrintStream& out, const InstructionStream::Ref& it, const ICStatusMap& = ICStatusMap());
 84  
 85      BytecodeDumper(Block* block, PrintStream& out)
 86          : BytecodeDumperBase(out)
 87          , m_block(block)
 88      {
 89      }
 90  
 91      ~BytecodeDumper() override { }
 92  
 93  protected:
 94      Block* block() const { return m_block; }
 95  
 96      void dumpBytecode(const InstructionStream::Ref& it, const ICStatusMap&);
 97  
 98      CString registerName(VirtualRegister) const override;
 99      int outOfLineJumpOffset(InstructionStream::Offset offset) const override;
100  
101  private:
102      virtual CString constantName(VirtualRegister) const;
103  
104      Block* m_block;
105  };
106  
107  template<class Block>
108  class CodeBlockBytecodeDumper final : public BytecodeDumper<Block> {
109  public:
110      static void dumpBlock(Block*, const InstructionStream&, PrintStream& out, const ICStatusMap& = ICStatusMap());
111      static void dumpGraph(Block*, const InstructionStream&, BytecodeGraph&, PrintStream& out = WTF::dataFile(), const ICStatusMap& = ICStatusMap());
112  
113      void dumpIdentifiers();
114      void dumpConstants();
115      void dumpExceptionHandlers();
116      void dumpSwitchJumpTables();
117      void dumpStringSwitchJumpTables();
118  
119  private:
120      using BytecodeDumper<Block>::BytecodeDumper;
121  
122      ALWAYS_INLINE VM& vm() const;
123  
124      const Identifier& identifier(int index) const;
125  };
126  
127  #if ENABLE(WEBASSEMBLY)
128  
129  namespace Wasm {
130  
131  class FunctionCodeBlock;
132  struct ModuleInformation;
133  enum Type : int8_t;
134  
135  class BytecodeDumper final : public JSC::BytecodeDumper<FunctionCodeBlock> {
136  public:
137      static void dumpBlock(FunctionCodeBlock*, const ModuleInformation&, PrintStream& out);
138  
139  private:
140      using JSC::BytecodeDumper<FunctionCodeBlock>::BytecodeDumper;
141  
142      void dumpConstants();
143      CString constantName(VirtualRegister index) const final;
144      CString formatConstant(Type, uint64_t) const;
145  };
146  
147  } // namespace Wasm
148  
149  #endif // ENABLE(WEBASSEMBLY)
150  
151  }