| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ | 5 #ifndef V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ |
| 6 #define V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ | 6 #define V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ |
| 7 | 7 |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "src/ast.h" | 10 #include "src/ast.h" |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 | 80 |
| 81 // Tests. | 81 // Tests. |
| 82 BytecodeArrayBuilder& CompareOperation(Token::Value op, Register reg, | 82 BytecodeArrayBuilder& CompareOperation(Token::Value op, Register reg, |
| 83 LanguageMode language_mode); | 83 LanguageMode language_mode); |
| 84 | 84 |
| 85 // Casts | 85 // Casts |
| 86 BytecodeArrayBuilder& CastAccumulatorToBoolean(); | 86 BytecodeArrayBuilder& CastAccumulatorToBoolean(); |
| 87 | 87 |
| 88 // Flow Control. | 88 // Flow Control. |
| 89 BytecodeArrayBuilder& Bind(BytecodeLabel* label); | 89 BytecodeArrayBuilder& Bind(BytecodeLabel* label); |
| 90 BytecodeArrayBuilder& Bind(const BytecodeLabel& target, BytecodeLabel* label); |
| 91 |
| 90 BytecodeArrayBuilder& Jump(BytecodeLabel* label); | 92 BytecodeArrayBuilder& Jump(BytecodeLabel* label); |
| 91 BytecodeArrayBuilder& JumpIfTrue(BytecodeLabel* label); | 93 BytecodeArrayBuilder& JumpIfTrue(BytecodeLabel* label); |
| 92 BytecodeArrayBuilder& JumpIfFalse(BytecodeLabel* label); | 94 BytecodeArrayBuilder& JumpIfFalse(BytecodeLabel* label); |
| 93 BytecodeArrayBuilder& Return(); | 95 BytecodeArrayBuilder& Return(); |
| 94 | 96 |
| 95 BytecodeArrayBuilder& EnterBlock(); | 97 BytecodeArrayBuilder& EnterBlock(); |
| 96 BytecodeArrayBuilder& LeaveBlock(); | 98 BytecodeArrayBuilder& LeaveBlock(); |
| 97 | 99 |
| 100 // Accessors |
| 101 Zone* zone() const { return zone_; } |
| 102 |
| 98 private: | 103 private: |
| 99 ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; } | 104 ZoneVector<uint8_t>* bytecodes() { return &bytecodes_; } |
| 100 const ZoneVector<uint8_t>* bytecodes() const { return &bytecodes_; } | 105 const ZoneVector<uint8_t>* bytecodes() const { return &bytecodes_; } |
| 101 Isolate* isolate() const { return isolate_; } | 106 Isolate* isolate() const { return isolate_; } |
| 102 | 107 |
| 103 static Bytecode BytecodeForBinaryOperation(Token::Value op); | 108 static Bytecode BytecodeForBinaryOperation(Token::Value op); |
| 104 static Bytecode BytecodeForCompareOperation(Token::Value op); | 109 static Bytecode BytecodeForCompareOperation(Token::Value op); |
| 105 static bool FitsInIdxOperand(int value); | 110 static bool FitsInIdxOperand(int value); |
| 106 static bool FitsInIdxOperand(size_t value); | 111 static bool FitsInIdxOperand(size_t value); |
| 107 static bool FitsInImm8Operand(int value); | 112 static bool FitsInImm8Operand(int value); |
| 108 static bool IsJumpWithImm8Operand(Bytecode jump_bytecode); | |
| 109 static Bytecode GetJumpWithConstantOperand(Bytecode jump_with_smi8_operand); | 113 static Bytecode GetJumpWithConstantOperand(Bytecode jump_with_smi8_operand); |
| 110 | 114 |
| 111 template <size_t N> | 115 template <size_t N> |
| 112 INLINE(void Output(uint8_t(&bytes)[N])); | 116 INLINE(void Output(uint8_t(&bytes)[N])); |
| 113 void Output(Bytecode bytecode, uint8_t operand0, uint8_t operand1, | 117 void Output(Bytecode bytecode, uint8_t operand0, uint8_t operand1, |
| 114 uint8_t operand2); | 118 uint8_t operand2); |
| 115 void Output(Bytecode bytecode, uint8_t operand0, uint8_t operand1); | 119 void Output(Bytecode bytecode, uint8_t operand0, uint8_t operand1); |
| 116 void Output(Bytecode bytecode, uint8_t operand0); | 120 void Output(Bytecode bytecode, uint8_t operand0); |
| 117 void Output(Bytecode bytecode); | 121 void Output(Bytecode bytecode); |
| 118 void PatchJump(const ZoneVector<uint8_t>::iterator& jump_target, | 122 void PatchJump(const ZoneVector<uint8_t>::iterator& jump_target, |
| 119 ZoneVector<uint8_t>::iterator jump_location); | 123 ZoneVector<uint8_t>::iterator jump_location); |
| 120 BytecodeArrayBuilder& OutputJump(Bytecode jump_bytecode, | 124 BytecodeArrayBuilder& OutputJump(Bytecode jump_bytecode, |
| 121 BytecodeLabel* label); | 125 BytecodeLabel* label); |
| 122 | 126 |
| 123 void EnsureReturn(); | 127 void EnsureReturn(); |
| 124 | 128 |
| 125 bool OperandIsValid(Bytecode bytecode, int operand_index, | 129 bool OperandIsValid(Bytecode bytecode, int operand_index, |
| 126 uint8_t operand_value) const; | 130 uint8_t operand_value) const; |
| 127 bool LastBytecodeInSameBlock() const; | 131 bool LastBytecodeInSameBlock() const; |
| 128 | 132 |
| 129 size_t GetConstantPoolEntry(Handle<Object> object); | 133 size_t GetConstantPoolEntry(Handle<Object> object); |
| 130 | 134 |
| 131 // Scope helpers used by TemporaryRegisterScope | 135 // Scope helpers used by TemporaryRegisterScope |
| 132 int BorrowTemporaryRegister(); | 136 int BorrowTemporaryRegister(); |
| 133 void ReturnTemporaryRegister(int reg_index); | 137 void ReturnTemporaryRegister(int reg_index); |
| 134 | 138 |
| 135 Isolate* isolate_; | 139 Isolate* isolate_; |
| 140 Zone* zone_; |
| 136 ZoneVector<uint8_t> bytecodes_; | 141 ZoneVector<uint8_t> bytecodes_; |
| 137 bool bytecode_generated_; | 142 bool bytecode_generated_; |
| 138 size_t last_block_end_; | 143 size_t last_block_end_; |
| 139 size_t last_bytecode_start_; | 144 size_t last_bytecode_start_; |
| 140 bool return_seen_in_block_; | 145 bool return_seen_in_block_; |
| 141 | 146 |
| 142 IdentityMap<size_t> constants_map_; | 147 IdentityMap<size_t> constants_map_; |
| 143 ZoneVector<Handle<Object>> constants_; | 148 ZoneVector<Handle<Object>> constants_; |
| 144 | 149 |
| 145 int parameter_count_; | 150 int parameter_count_; |
| 146 int local_register_count_; | 151 int local_register_count_; |
| 147 int temporary_register_count_; | 152 int temporary_register_count_; |
| 148 int temporary_register_next_; | 153 int temporary_register_next_; |
| 149 | 154 |
| 150 friend class TemporaryRegisterScope; | 155 friend class TemporaryRegisterScope; |
| 151 DISALLOW_IMPLICIT_CONSTRUCTORS(BytecodeArrayBuilder); | 156 DISALLOW_IMPLICIT_CONSTRUCTORS(BytecodeArrayBuilder); |
| 152 }; | 157 }; |
| 153 | 158 |
| 154 | 159 |
| 155 // A label representing a branch target in a bytecode array. When a | 160 // A label representing a branch target in a bytecode array. When a |
| 156 // label is bound, it represents a known position in the bytecode | 161 // label is bound, it represents a known position in the bytecode |
| 157 // array. For labels that are forward references there can be at most | 162 // array. For labels that are forward references there can be at most |
| 158 // one reference whilst it is unbound. | 163 // one reference whilst it is unbound. |
| 159 class BytecodeLabel final { | 164 class BytecodeLabel final { |
| 160 public: | 165 public: |
| 161 BytecodeLabel() : bound_(false), offset_(kInvalidOffset) {} | 166 BytecodeLabel() : bound_(false), offset_(kInvalidOffset) {} |
| 162 ~BytecodeLabel() { DCHECK(bound_ && offset_ != kInvalidOffset); } | |
| 163 | 167 |
| 164 private: | 168 private: |
| 165 static const size_t kInvalidOffset = static_cast<size_t>(-1); | 169 static const size_t kInvalidOffset = static_cast<size_t>(-1); |
| 166 | 170 |
| 167 INLINE(void bind_to(size_t offset)) { | 171 INLINE(void bind_to(size_t offset)) { |
| 168 DCHECK(!bound_ && offset != kInvalidOffset); | 172 DCHECK(!bound_ && offset != kInvalidOffset); |
| 169 offset_ = offset; | 173 offset_ = offset; |
| 170 bound_ = true; | 174 bound_ = true; |
| 171 } | 175 } |
| 172 INLINE(void set_referrer(size_t offset)) { | 176 INLINE(void set_referrer(size_t offset)) { |
| 173 DCHECK(!bound_ && offset != kInvalidOffset); | 177 DCHECK(!bound_ && offset != kInvalidOffset); |
| 174 offset_ = offset; | 178 offset_ = offset; |
| 175 } | 179 } |
| 176 INLINE(size_t offset() const) { return offset_; } | 180 INLINE(size_t offset() const) { return offset_; } |
| 177 INLINE(bool is_bound() const) { return bound_; } | 181 INLINE(bool is_bound() const) { return bound_; } |
| 178 INLINE(bool is_forward_target() const) { | 182 INLINE(bool is_forward_target() const) { |
| 179 return offset() != kInvalidOffset && !is_bound(); | 183 return offset() != kInvalidOffset && !is_bound(); |
| 180 } | 184 } |
| 181 | 185 |
| 182 // There are three states for a label: | 186 // There are three states for a label: |
| 183 // bound_ offset_ | 187 // bound_ offset_ |
| 184 // UNSET false kInvalidOffset | 188 // UNSET false kInvalidOffset |
| 185 // FORWARD_TARGET false Offset of referring jump | 189 // FORWARD_TARGET false Offset of referring jump |
| 186 // BACKWARD_TARGET true Offset of label in bytecode array when bound | 190 // BACKWARD_TARGET true Offset of label in bytecode array when bound |
| 187 bool bound_; | 191 bool bound_; |
| 188 size_t offset_; | 192 size_t offset_; |
| 189 | 193 |
| 190 friend class BytecodeArrayBuilder; | 194 friend class BytecodeArrayBuilder; |
| 191 DISALLOW_COPY_AND_ASSIGN(BytecodeLabel); | |
| 192 }; | 195 }; |
| 193 | 196 |
| 194 | 197 |
| 195 // A stack-allocated class than allows the instantiator to allocate | 198 // A stack-allocated class than allows the instantiator to allocate |
| 196 // temporary registers that are cleaned up when scope is closed. | 199 // temporary registers that are cleaned up when scope is closed. |
| 197 class TemporaryRegisterScope { | 200 class TemporaryRegisterScope { |
| 198 public: | 201 public: |
| 199 explicit TemporaryRegisterScope(BytecodeArrayBuilder* builder); | 202 explicit TemporaryRegisterScope(BytecodeArrayBuilder* builder); |
| 200 ~TemporaryRegisterScope(); | 203 ~TemporaryRegisterScope(); |
| 201 Register NewRegister(); | 204 Register NewRegister(); |
| 202 | 205 |
| 203 private: | 206 private: |
| 204 void* operator new(size_t size); | 207 void* operator new(size_t size); |
| 205 void operator delete(void* p); | 208 void operator delete(void* p); |
| 206 | 209 |
| 207 BytecodeArrayBuilder* builder_; | 210 BytecodeArrayBuilder* builder_; |
| 208 int count_; | 211 int count_; |
| 209 int last_register_index_; | 212 int last_register_index_; |
| 210 | 213 |
| 211 DISALLOW_COPY_AND_ASSIGN(TemporaryRegisterScope); | 214 DISALLOW_COPY_AND_ASSIGN(TemporaryRegisterScope); |
| 212 }; | 215 }; |
| 213 | 216 |
| 214 | 217 |
| 215 } // namespace interpreter | 218 } // namespace interpreter |
| 216 } // namespace internal | 219 } // namespace internal |
| 217 } // namespace v8 | 220 } // namespace v8 |
| 218 | 221 |
| 219 #endif // V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ | 222 #endif // V8_INTERPRETER_BYTECODE_ARRAY_BUILDER_H_ |
| OLD | NEW |