| 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 #include "src/interpreter/bytecode-array-writer.h" | 5 #include "src/interpreter/bytecode-array-writer.h" | 
| 6 | 6 | 
| 7 #include "src/api.h" | 7 #include "src/api.h" | 
| 8 #include "src/interpreter/bytecode-label.h" | 8 #include "src/interpreter/bytecode-label.h" | 
| 9 #include "src/interpreter/constant-array-builder.h" | 9 #include "src/interpreter/constant-array-builder.h" | 
| 10 #include "src/log.h" | 10 #include "src/log.h" | 
| 11 | 11 | 
| 12 namespace v8 { | 12 namespace v8 { | 
| 13 namespace internal { | 13 namespace internal { | 
| 14 namespace interpreter { | 14 namespace interpreter { | 
| 15 | 15 | 
|  | 16 STATIC_CONST_MEMBER_DEFINITION const size_t | 
|  | 17     BytecodeArrayWriter::kMaxSizeOfPackedBytecode; | 
|  | 18 | 
| 16 BytecodeArrayWriter::BytecodeArrayWriter( | 19 BytecodeArrayWriter::BytecodeArrayWriter( | 
| 17     Isolate* isolate, Zone* zone, ConstantArrayBuilder* constant_array_builder) | 20     Isolate* isolate, Zone* zone, ConstantArrayBuilder* constant_array_builder) | 
| 18     : isolate_(isolate), | 21     : isolate_(isolate), | 
| 19       bytecodes_(zone), | 22       bytecodes_(zone), | 
| 20       max_register_count_(0), | 23       max_register_count_(0), | 
| 21       unbound_jumps_(0), | 24       unbound_jumps_(0), | 
| 22       source_position_table_builder_(isolate, zone), | 25       source_position_table_builder_(isolate, zone), | 
| 23       constant_array_builder_(constant_array_builder) { | 26       constant_array_builder_(constant_array_builder) { | 
| 24   LOG_CODE_EVENT(isolate_, CodeStartLinePosInfoRecordEvent( | 27   LOG_CODE_EVENT(isolate_, CodeStartLinePosInfoRecordEvent( | 
| 25                                source_position_table_builder())); | 28                                source_position_table_builder())); | 
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 125 | 128 | 
| 126 OperandScale OperandScaleForScalableUnsignedByte(uint32_t operand_value) { | 129 OperandScale OperandScaleForScalableUnsignedByte(uint32_t operand_value) { | 
| 127   OperandSize bytes_required = Bytecodes::SizeForUnsignedOperand(operand_value); | 130   OperandSize bytes_required = Bytecodes::SizeForUnsignedOperand(operand_value); | 
| 128   return ScaleForScalableByteOperand(bytes_required); | 131   return ScaleForScalableByteOperand(bytes_required); | 
| 129 } | 132 } | 
| 130 | 133 | 
| 131 OperandScale GetOperandScale(const BytecodeNode* const node) { | 134 OperandScale GetOperandScale(const BytecodeNode* const node) { | 
| 132   const OperandTypeInfo* operand_type_infos = | 135   const OperandTypeInfo* operand_type_infos = | 
| 133       Bytecodes::GetOperandTypeInfos(node->bytecode()); | 136       Bytecodes::GetOperandTypeInfos(node->bytecode()); | 
| 134   OperandScale operand_scale = OperandScale::kSingle; | 137   OperandScale operand_scale = OperandScale::kSingle; | 
| 135   for (int i = 0; i < node->operand_count(); ++i) { | 138   int operand_count = node->operand_count(); | 
|  | 139   for (int i = 0; i < operand_count; ++i) { | 
| 136     switch (operand_type_infos[i]) { | 140     switch (operand_type_infos[i]) { | 
| 137       case OperandTypeInfo::kScalableSignedByte: { | 141       case OperandTypeInfo::kScalableSignedByte: { | 
| 138         uint32_t operand = node->operand(i); | 142         uint32_t operand = node->operand(i); | 
| 139         operand_scale = | 143         operand_scale = | 
| 140             std::max(operand_scale, OperandScaleForScalableSignedByte(operand)); | 144             std::max(operand_scale, OperandScaleForScalableSignedByte(operand)); | 
| 141         break; | 145         break; | 
| 142       } | 146       } | 
| 143       case OperandTypeInfo::kScalableUnsignedByte: { | 147       case OperandTypeInfo::kScalableUnsignedByte: { | 
| 144         uint32_t operand = node->operand(i); | 148         uint32_t operand = node->operand(i); | 
| 145         operand_scale = std::max(operand_scale, | 149         operand_scale = std::max(operand_scale, | 
| 146                                  OperandScaleForScalableUnsignedByte(operand)); | 150                                  OperandScaleForScalableUnsignedByte(operand)); | 
| 147         break; | 151         break; | 
| 148       } | 152       } | 
| 149       case OperandTypeInfo::kFixedUnsignedByte: | 153       case OperandTypeInfo::kFixedUnsignedByte: | 
| 150       case OperandTypeInfo::kFixedUnsignedShort: | 154       case OperandTypeInfo::kFixedUnsignedShort: | 
| 151         break; | 155         break; | 
| 152       case OperandTypeInfo::kNone: | 156       case OperandTypeInfo::kNone: | 
| 153         UNREACHABLE(); | 157         UNREACHABLE(); | 
| 154         break; | 158         break; | 
| 155     } | 159     } | 
| 156   } | 160   } | 
| 157   return operand_scale; | 161   return operand_scale; | 
| 158 } | 162 } | 
| 159 | 163 | 
| 160 }  // namespace | 164 }  // namespace | 
| 161 | 165 | 
| 162 void BytecodeArrayWriter::EmitBytecode(const BytecodeNode* const node) { | 166 void BytecodeArrayWriter::EmitBytecode(const BytecodeNode* const node) { | 
| 163   DCHECK_NE(node->bytecode(), Bytecode::kIllegal); | 167   DCHECK_NE(node->bytecode(), Bytecode::kIllegal); | 
| 164 | 168 | 
|  | 169   uint8_t buffer[kMaxSizeOfPackedBytecode]; | 
|  | 170   uint8_t* buffer_limit = buffer; | 
|  | 171 | 
| 165   OperandScale operand_scale = GetOperandScale(node); | 172   OperandScale operand_scale = GetOperandScale(node); | 
| 166   if (operand_scale != OperandScale::kSingle) { | 173   if (operand_scale != OperandScale::kSingle) { | 
| 167     Bytecode prefix = Bytecodes::OperandScaleToPrefixBytecode(operand_scale); | 174     Bytecode prefix = Bytecodes::OperandScaleToPrefixBytecode(operand_scale); | 
| 168     bytecodes()->push_back(Bytecodes::ToByte(prefix)); | 175     *buffer_limit++ = Bytecodes::ToByte(prefix); | 
| 169   } | 176   } | 
| 170 | 177 | 
| 171   Bytecode bytecode = node->bytecode(); | 178   Bytecode bytecode = node->bytecode(); | 
| 172   bytecodes()->push_back(Bytecodes::ToByte(bytecode)); | 179   *buffer_limit++ = Bytecodes::ToByte(bytecode); | 
| 173 | 180 | 
| 174   int register_operand_bitmap = Bytecodes::GetRegisterOperandBitmap(bytecode); |  | 
| 175   const uint32_t* const operands = node->operands(); | 181   const uint32_t* const operands = node->operands(); | 
| 176   const OperandSize* operand_sizes = |  | 
| 177       Bytecodes::GetOperandSizes(bytecode, operand_scale); |  | 
| 178   const OperandType* operand_types = Bytecodes::GetOperandTypes(bytecode); | 182   const OperandType* operand_types = Bytecodes::GetOperandTypes(bytecode); | 
| 179   for (int i = 0; operand_types[i] != OperandType::kNone; ++i) { | 183   const int operand_count = Bytecodes::NumberOfOperands(bytecode); | 
| 180     OperandType operand_type = operand_types[i]; | 184   for (int i = 0; i < operand_count; ++i) { | 
| 181     switch (operand_sizes[i]) { | 185     OperandSize operand_size = | 
|  | 186         Bytecodes::SizeOfOperand(operand_types[i], operand_scale); | 
|  | 187     switch (operand_size) { | 
| 182       case OperandSize::kNone: | 188       case OperandSize::kNone: | 
| 183         UNREACHABLE(); | 189         UNREACHABLE(); | 
| 184         break; | 190         break; | 
| 185       case OperandSize::kByte: | 191       case OperandSize::kByte: | 
| 186         bytecodes()->push_back(static_cast<uint8_t>(operands[i])); | 192         *buffer_limit++ = static_cast<uint8_t>(operands[i]); | 
| 187         break; | 193         break; | 
| 188       case OperandSize::kShort: { | 194       case OperandSize::kShort: { | 
| 189         uint8_t operand_bytes[2]; | 195         WriteUnalignedUInt16(buffer_limit, operands[i]); | 
| 190         WriteUnalignedUInt16(operand_bytes, operands[i]); | 196         buffer_limit += 2; | 
| 191         bytecodes()->insert(bytecodes()->end(), operand_bytes, |  | 
| 192                             operand_bytes + 2); |  | 
| 193         break; | 197         break; | 
| 194       } | 198       } | 
| 195       case OperandSize::kQuad: { | 199       case OperandSize::kQuad: { | 
| 196         uint8_t operand_bytes[4]; | 200         WriteUnalignedUInt32(buffer_limit, operands[i]); | 
| 197         WriteUnalignedUInt32(operand_bytes, operands[i]); | 201         buffer_limit += 4; | 
| 198         bytecodes()->insert(bytecodes()->end(), operand_bytes, |  | 
| 199                             operand_bytes + 4); |  | 
| 200         break; | 202         break; | 
| 201       } | 203       } | 
| 202     } | 204     } | 
| 203 | 205 | 
| 204     if ((register_operand_bitmap >> i) & 1) { | 206     int count = Bytecodes::GetNumberOfRegistersRepresentedBy(operand_types[i]); | 
| 205       int count; | 207     if (count == 0) { | 
| 206       if (operand_types[i + 1] == OperandType::kRegCount) { | 208       continue; | 
| 207         count = static_cast<int>(operands[i + 1]); |  | 
| 208       } else { |  | 
| 209         count = Bytecodes::GetNumberOfRegistersRepresentedBy(operand_type); |  | 
| 210       } |  | 
| 211       Register reg = Register::FromOperand(static_cast<int32_t>(operands[i])); |  | 
| 212       max_register_count_ = std::max(max_register_count_, reg.index() + count); |  | 
| 213     } | 209     } | 
|  | 210     // NB operand_types is terminated by OperandType::kNone so | 
|  | 211     // operand_types[i + 1] is valid whilst i < operand_count. | 
|  | 212     if (operand_types[i + 1] == OperandType::kRegCount) { | 
|  | 213       count = static_cast<int>(operands[i]); | 
|  | 214     } | 
|  | 215     Register reg = Register::FromOperand(static_cast<int32_t>(operands[i])); | 
|  | 216     max_register_count_ = std::max(max_register_count_, reg.index() + count); | 
| 214   } | 217   } | 
|  | 218 | 
|  | 219   DCHECK_LE(buffer_limit, buffer + sizeof(buffer)); | 
|  | 220   bytecodes()->insert(bytecodes()->end(), buffer, buffer_limit); | 
| 215 } | 221 } | 
| 216 | 222 | 
| 217 // static | 223 // static | 
| 218 Bytecode GetJumpWithConstantOperand(Bytecode jump_bytecode) { | 224 Bytecode GetJumpWithConstantOperand(Bytecode jump_bytecode) { | 
| 219   switch (jump_bytecode) { | 225   switch (jump_bytecode) { | 
| 220     case Bytecode::kJump: | 226     case Bytecode::kJump: | 
| 221       return Bytecode::kJumpConstant; | 227       return Bytecode::kJumpConstant; | 
| 222     case Bytecode::kJumpIfTrue: | 228     case Bytecode::kJumpIfTrue: | 
| 223       return Bytecode::kJumpIfTrueConstant; | 229       return Bytecode::kJumpIfTrueConstant; | 
| 224     case Bytecode::kJumpIfFalse: | 230     case Bytecode::kJumpIfFalse: | 
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 381         node->set_bytecode(node->bytecode(), k32BitJumpPlaceholder); | 387         node->set_bytecode(node->bytecode(), k32BitJumpPlaceholder); | 
| 382         break; | 388         break; | 
| 383     } | 389     } | 
| 384   } | 390   } | 
| 385   EmitBytecode(node); | 391   EmitBytecode(node); | 
| 386 } | 392 } | 
| 387 | 393 | 
| 388 }  // namespace interpreter | 394 }  // namespace interpreter | 
| 389 }  // namespace internal | 395 }  // namespace internal | 
| 390 }  // namespace v8 | 396 }  // namespace v8 | 
| OLD | NEW | 
|---|