Disasm-arm.h (4058B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 */ 4 // Copyright 2007-2008 the V8 project authors. All rights reserved. 5 // Use of this source code is governed by a BSD-style license that can be 6 // found in the LICENSE file. 7 8 #ifndef jit_arm_disasm_Disasm_arm_h 9 #define jit_arm_disasm_Disasm_arm_h 10 11 #ifdef JS_DISASM_ARM 12 13 # include "mozilla/Assertions.h" 14 15 # include <stdio.h> 16 17 namespace js { 18 namespace jit { 19 namespace disasm { 20 21 typedef unsigned char byte; 22 23 // A reasonable (ie, safe) buffer size for the disassembly of a single 24 // instruction. 25 const int ReasonableBufferSize = 256; 26 27 // Vector as used by the original code to allow for minimal modification. 28 // Functions exactly like a character array with helper methods. 29 template <typename T> 30 class V8Vector { 31 public: 32 V8Vector() : start_(nullptr), length_(0) {} 33 V8Vector(T* data, int length) : start_(data), length_(length) { 34 MOZ_ASSERT(length == 0 || (length > 0 && data != nullptr)); 35 } 36 37 // Returns the length of the vector. 38 int length() const { return length_; } 39 40 // Returns the pointer to the start of the data in the vector. 41 T* start() const { return start_; } 42 43 // Access individual vector elements - checks bounds in debug mode. 44 T& operator[](int index) const { 45 MOZ_ASSERT(0 <= index && index < length_); 46 return start_[index]; 47 } 48 49 V8Vector<T> operator+(int offset) const { 50 MOZ_ASSERT(offset < length_); 51 return V8Vector<T>(start_ + offset, length_ - offset); 52 } 53 54 private: 55 T* start_; 56 int length_; 57 }; 58 59 template <typename T, int kSize> 60 class EmbeddedVector : public V8Vector<T> { 61 public: 62 EmbeddedVector() : V8Vector<T>(buffer_, kSize) {} 63 64 explicit EmbeddedVector(T initial_value) : V8Vector<T>(buffer_, kSize) { 65 for (int i = 0; i < kSize; ++i) { 66 buffer_[i] = initial_value; 67 } 68 } 69 70 // When copying, make underlying Vector to reference our buffer. 71 EmbeddedVector(const EmbeddedVector& rhs) : V8Vector<T>(rhs) { 72 MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize); 73 this->set_start(buffer_); 74 } 75 76 EmbeddedVector& operator=(const EmbeddedVector& rhs) { 77 if (this == &rhs) return *this; 78 V8Vector<T>::operator=(rhs); 79 MemCopy(buffer_, rhs.buffer_, sizeof(T) * kSize); 80 this->set_start(buffer_); 81 return *this; 82 } 83 84 private: 85 T buffer_[kSize]; 86 }; 87 88 // Interface and default implementation for converting addresses and 89 // register-numbers to text. The default implementation is machine 90 // specific. 91 class NameConverter { 92 public: 93 virtual ~NameConverter() {} 94 virtual const char* NameOfCPURegister(int reg) const; 95 virtual const char* NameOfByteCPURegister(int reg) const; 96 virtual const char* NameOfXMMRegister(int reg) const; 97 virtual const char* NameOfAddress(byte* addr) const; 98 virtual const char* NameOfConstant(byte* addr) const; 99 virtual const char* NameInCode(byte* addr) const; 100 101 protected: 102 EmbeddedVector<char, 128> tmp_buffer_; 103 }; 104 105 // A generic Disassembler interface 106 class Disassembler { 107 public: 108 // Caller deallocates converter. 109 explicit Disassembler(const NameConverter& converter); 110 111 virtual ~Disassembler(); 112 113 // Writes one disassembled instruction into 'buffer' (0-terminated). 114 // Returns the length of the disassembled machine instruction in bytes. 115 int InstructionDecode(V8Vector<char> buffer, uint8_t* instruction); 116 117 // Returns -1 if instruction does not mark the beginning of a constant pool, 118 // or the number of entries in the constant pool beginning here. 119 int ConstantPoolSizeAt(byte* instruction); 120 121 // Write disassembly into specified file 'f' using specified NameConverter 122 // (see constructor). 123 static void Disassemble(FILE* f, uint8_t* begin, uint8_t* end); 124 125 private: 126 const NameConverter& converter_; 127 128 // Disallow implicit constructors. 129 Disassembler() = delete; 130 Disassembler(const Disassembler&) = delete; 131 void operator=(const Disassembler&) = delete; 132 }; 133 134 } // namespace disasm 135 } // namespace jit 136 } // namespace js 137 138 #endif // JS_DISASM_ARM 139 140 #endif // jit_arm_disasm_Disasm_arm_h